Reintroduce open/close of net cards. Clean up ofnet.

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-07-05 16:37:14 +02:00
parent 382077365b
commit 0bc2cd0f82
12 changed files with 313 additions and 285 deletions

View file

@ -115,7 +115,6 @@ endif
if COND_i386_ieee1275 if COND_i386_ieee1275
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ofnet.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
@ -175,7 +174,6 @@ endif
if COND_powerpc_ieee1275 if COND_powerpc_ieee1275
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ofnet.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
@ -183,7 +181,6 @@ endif
if COND_sparc64_ieee1275 if COND_sparc64_ieee1275
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ofnet.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h

View file

@ -31,7 +31,6 @@
#include <grub/ieee1275/console.h> #include <grub/ieee1275/console.h>
#include <grub/ieee1275/ofdisk.h> #include <grub/ieee1275/ofdisk.h>
#include <grub/ieee1275/ieee1275.h> #include <grub/ieee1275/ieee1275.h>
#include <grub/ieee1275/ofnet.h>
#include <grub/net.h> #include <grub/net.h>
#include <grub/offsets.h> #include <grub/offsets.h>
#include <grub/memory.h> #include <grub/memory.h>
@ -77,24 +76,15 @@ grub_translate_ieee1275_path (char *filepath)
} }
} }
void (*grub_ieee1275_net_config) (const char *dev,
char **device,
char **path);
void void
grub_machine_get_bootlocation (char **device, char **path) grub_machine_get_bootlocation (char **device, char **path)
{ {
char bootpath[64]; /* XXX check length */ char bootpath[64]; /* XXX check length */
char *filename; char *filename;
grub_bootp_t bootp_pckt; char *type;
/* Set the net prefix when possible. */
if (grub_getbootp && (bootp_pckt = grub_getbootp()))
{
grub_uint32_t n = bootp_pckt->siaddr;
char addr[GRUB_NET_MAX_STR_ADDR_LEN];
grub_snprintf (addr, GRUB_NET_MAX_STR_ADDR_LEN, "%d.%d.%d.%d",
((n >> 24) & 0xff), ((n >> 16) & 0xff),
((n >> 8) & 0xff), ((n >> 0) & 0xff));
*device = grub_xasprintf ("(tftp,%s)", addr);
return;
}
if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath, if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath,
sizeof (bootpath), 0)) sizeof (bootpath), 0))
@ -106,7 +96,27 @@ grub_machine_get_bootlocation (char **device, char **path)
/* Transform an OF device path to a GRUB path. */ /* Transform an OF device path to a GRUB path. */
*device = grub_ieee1275_encode_devname (bootpath); type = grub_ieee1275_get_device_type (bootpath);
if (type && grub_strcmp (type, "network") == 0)
{
char *dev, *canon;
char *ptr;
dev = grub_ieee1275_get_aliasdevname (bootpath);
canon = grub_ieee1275_canonicalise_devname (dev);
ptr = canon + grub_strlen (canon) - 1;
while (ptr > canon && (*ptr == ',' || *ptr == ':'))
ptr--;
ptr++;
*ptr = 0;
if (grub_ieee1275_net_config)
grub_ieee1275_net_config (canon, device, path);
grub_free (dev);
grub_free (canon);
}
else
*device = grub_ieee1275_encode_devname (bootpath);
grub_free (type);
filename = grub_ieee1275_get_filename (bootpath); filename = grub_ieee1275_get_filename (bootpath);
if (filename) if (filename)
@ -264,8 +274,6 @@ grub_machine_init (void)
void void
grub_machine_fini (void) grub_machine_fini (void)
{ {
if (grub_grubnet_fini)
grub_grubnet_fini ();
grub_ofdisk_fini (); grub_ofdisk_fini ();
grub_console_fini (); grub_console_fini ();
} }

View file

@ -22,16 +22,15 @@
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/ieee1275/ieee1275.h> #include <grub/ieee1275/ieee1275.h>
#include <grub/ieee1275/ofnet.h>
#include <grub/net.h> #include <grub/net.h>
#include <grub/net/tftp.h> #include <grub/net/tftp.h>
grub_bootp_t (*grub_getbootp) (void);
enum grub_ieee1275_parse_type enum grub_ieee1275_parse_type
{ {
GRUB_PARSE_FILENAME, GRUB_PARSE_FILENAME,
GRUB_PARSE_PARTITION, GRUB_PARSE_PARTITION,
GRUB_PARSE_DEVICE GRUB_PARSE_DEVICE,
GRUB_PARSE_DEVICE_TYPE
}; };
/* Walk children of 'devpath', calling hook for each. */ /* Walk children of 'devpath', calling hook for each. */
@ -322,14 +321,9 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype)
{ {
char type[64]; /* XXX check size. */ char type[64]; /* XXX check size. */
char *device = grub_ieee1275_get_devname (path); char *device = grub_ieee1275_get_devname (path);
char *args = grub_ieee1275_get_devargs (path);
char *ret = 0; char *ret = 0;
grub_ieee1275_phandle_t dev; grub_ieee1275_phandle_t dev;
if (!args)
/* Shouldn't happen. */
return 0;
/* We need to know what type of device it is in order to parse the full /* We need to know what type of device it is in order to parse the full
file path properly. */ file path properly. */
if (grub_ieee1275_finddevice (device, &dev)) if (grub_ieee1275_finddevice (device, &dev))
@ -344,55 +338,86 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype)
goto fail; goto fail;
} }
if (!grub_strcmp ("block", type)) switch (ptype)
{ {
/* The syntax of the device arguments is defined in the CHRP and PReP case GRUB_PARSE_DEVICE:
IEEE1275 bindings: "[partition][,[filename]]". */ ret = grub_strdup (device);
char *comma = grub_strchr (args, ','); break;
case GRUB_PARSE_DEVICE_TYPE:
ret = grub_strdup (type);
break;
case GRUB_PARSE_FILENAME:
{
char *comma;
char *args;
if (ptype == GRUB_PARSE_FILENAME) if (grub_strcmp ("block", type) != 0)
{ goto unknown;
if (comma)
{
char *filepath = comma + 1;
/* Make sure filepath has leading backslash. */ args = grub_ieee1275_get_devargs (path);
if (filepath[0] != '\\') if (!args)
ret = grub_xasprintf ("\\%s", filepath); /* Shouldn't happen. */
else return 0;
ret = grub_strdup (filepath);
/* The syntax of the device arguments is defined in the CHRP and PReP
IEEE1275 bindings: "[partition][,[filename]]". */
comma = grub_strchr (args, ',');
if (comma)
{
char *filepath = comma + 1;
/* Make sure filepath has leading backslash. */
if (filepath[0] != '\\')
ret = grub_xasprintf ("\\%s", filepath);
else
ret = grub_strdup (filepath);
} }
grub_free (args);
} }
else if (ptype == GRUB_PARSE_PARTITION) break;
{ case GRUB_PARSE_PARTITION:
if (!comma) {
ret = grub_strdup (args); char *comma;
else char *args;
ret = grub_strndup (args, (grub_size_t)(comma - args));
/* Consistently provide numbered partitions to GRUB.
OpenBOOT traditionally uses alphabetical partition
specifiers. */
if (ret[0] >= 'a' && ret[0] <= 'z')
ret[0] = '1' + (ret[0] - 'a');
}
}
else if (!grub_strcmp ("network", type)) if (grub_strcmp ("block", type) != 0)
{ goto unknown;
if (ptype == GRUB_PARSE_DEVICE)
ret = grub_strdup(device); args = grub_ieee1275_get_devargs (path);
} if (!args)
else /* Shouldn't happen. */
{ return 0;
comma = grub_strchr (args, ',');
if (!comma)
ret = grub_strdup (args);
else
ret = grub_strndup (args, (grub_size_t)(comma - args));
/* Consistently provide numbered partitions to GRUB.
OpenBOOT traditionally uses alphabetical partition
specifiers. */
if (ret[0] >= 'a' && ret[0] <= 'z')
ret[0] = '1' + (ret[0] - 'a');
grub_free (args);
}
break;
default:
unknown:
grub_printf ("Unsupported type %s for device %s\n", type, device); grub_printf ("Unsupported type %s for device %s\n", type, device);
} }
fail: fail:
grub_free (device); grub_free (device);
grub_free (args);
return ret; return ret;
} }
char *
grub_ieee1275_get_device_type (const char *path)
{
return grub_ieee1275_parse_args (path, GRUB_PARSE_DEVICE_TYPE);
}
char * char *
grub_ieee1275_get_aliasdevname (const char *path) grub_ieee1275_get_aliasdevname (const char *path)
{ {

View file

@ -195,7 +195,7 @@ GRUB_MOD_FINI(efinet)
struct grub_net_card *card, *next; struct grub_net_card *card, *next;
FOR_NET_CARDS_SAFE (card, next) FOR_NET_CARDS_SAFE (card, next)
if (card->driver && grub_strcmp (card->driver->name, "efinet") == 0) if (card->driver == &efidriver)
grub_net_card_unregister (card); grub_net_card_unregister (card);
} }

View file

@ -23,7 +23,6 @@
#include <grub/file.h> #include <grub/file.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/env.h> #include <grub/env.h>
#include <grub/loader.h>
#include <grub/machine/pxe.h> #include <grub/machine/pxe.h>
#include <grub/machine/int.h> #include <grub/machine/int.h>
@ -261,20 +260,8 @@ grub_pxe_send (const struct grub_net_card *dev __attribute__ ((unused)),
return 0; return 0;
} }
struct grub_net_card_driver grub_pxe_card_driver =
{
.send = grub_pxe_send,
.recv = grub_pxe_recv
};
struct grub_net_card grub_pxe_card =
{
.driver = &grub_pxe_card_driver,
.name = "pxe"
};
static grub_err_t static grub_err_t
grub_pxe_fini_hw (int noreturn __attribute__ ((unused))) grub_pxe_close (const struct grub_net_card *dev __attribute__ ((unused)))
{ {
if (pxe_rm_entry) if (pxe_rm_entry)
grub_pxe_call (GRUB_PXENV_UNDI_CLOSE, grub_pxe_call (GRUB_PXENV_UNDI_CLOSE,
@ -285,7 +272,7 @@ grub_pxe_fini_hw (int noreturn __attribute__ ((unused)))
} }
static grub_err_t static grub_err_t
grub_pxe_restore_hw (void) grub_pxe_open (const struct grub_net_card *dev __attribute__ ((unused)))
{ {
struct grub_pxe_undi_open *ou; struct grub_pxe_undi_open *ou;
ou = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; ou = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
@ -294,14 +281,23 @@ grub_pxe_restore_hw (void)
grub_pxe_call (GRUB_PXENV_UNDI_OPEN, ou, pxe_rm_entry); grub_pxe_call (GRUB_PXENV_UNDI_OPEN, ou, pxe_rm_entry);
if (ou->status) if (ou->status)
{ return grub_error (GRUB_ERR_IO, "can't open UNDI");
grub_net_card_unregister (&grub_pxe_card);
return grub_error (GRUB_ERR_IO, "can't open UNDI");
}
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
static void *fini_hnd; struct grub_net_card_driver grub_pxe_card_driver =
{
.open = grub_pxe_open,
.close = grub_pxe_close,
.send = grub_pxe_send,
.recv = grub_pxe_recv
};
struct grub_net_card grub_pxe_card =
{
.driver = &grub_pxe_card_driver,
.name = "pxe"
};
static void static void
grub_pc_net_config_real (char **device, char **path) grub_pc_net_config_real (char **device, char **path)
@ -355,30 +351,12 @@ GRUB_MOD_INIT(pxe)
grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
ou = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
grub_memset (ou, 0, sizeof (*ou));
ou->pkt_filter = 4;
grub_pxe_call (GRUB_PXENV_UNDI_OPEN, ou, pxe_rm_entry);
if (ou->status)
return;
grub_net_card_register (&grub_pxe_card); grub_net_card_register (&grub_pxe_card);
grub_pc_net_config = grub_pc_net_config_real; grub_pc_net_config = grub_pc_net_config_real;
fini_hnd = grub_loader_register_preboot_hook (grub_pxe_fini_hw,
grub_pxe_restore_hw,
GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK);
} }
GRUB_MOD_FINI(pxe) GRUB_MOD_FINI(pxe)
{ {
struct grub_net_card *card, *next;
grub_pc_net_config = 0; grub_pc_net_config = 0;
grub_pxe_fini_hw (0);
grub_net_card_unregister (&grub_pxe_card); grub_net_card_unregister (&grub_pxe_card);
FOR_NET_CARDS_SAFE (card, next)
if (card->driver && grub_strcmp (card->driver->name, "pxe") == 0)
grub_net_card_unregister (card);
grub_loader_unregister_preboot_hook (fini_hnd);
} }

View file

@ -17,7 +17,6 @@
*/ */
#include <grub/net/netbuff.h> #include <grub/net/netbuff.h>
#include <grub/ieee1275/ofnet.h>
#include <grub/ieee1275/ieee1275.h> #include <grub/ieee1275/ieee1275.h>
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/net.h> #include <grub/net.h>
@ -25,8 +24,15 @@
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
struct grub_ofnetcard_data
{
char *path;
grub_ieee1275_ihandle_t handle;
grub_uint32_t mtu;
};
static grub_err_t static grub_err_t
card_open (struct grub_net_card *dev) card_open (const struct grub_net_card *dev)
{ {
int status; int status;
struct grub_ofnetcard_data *data = dev->data; struct grub_ofnetcard_data *data = dev->data;
@ -44,14 +50,13 @@ card_open (struct grub_net_card *dev)
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
static grub_err_t static void
card_close (struct grub_net_card *dev) card_close (const struct grub_net_card *dev)
{ {
struct grub_ofnetcard_data *data = dev->data; struct grub_ofnetcard_data *data = dev->data;
if (data->handle) if (data->handle)
grub_ieee1275_close (data->handle); grub_ieee1275_close (data->handle);
return GRUB_ERR_NONE;
} }
static grub_err_t static grub_err_t
@ -93,8 +98,8 @@ get_card_packet (const struct grub_net_card *dev, struct grub_net_buff *nb)
static struct grub_net_card_driver ofdriver = static struct grub_net_card_driver ofdriver =
{ {
.name = "ofnet", .name = "ofnet",
.init = card_open, .open = card_open,
.fini = card_close, .close = card_close,
.send = send_card_buffer, .send = send_card_buffer,
.recv = get_card_packet .recv = get_card_packet
}; };
@ -112,39 +117,87 @@ bootp_response_properties[] =
{ .name = "bootpreply-packet", .offset = 0x2a}, { .name = "bootpreply-packet", .offset = 0x2a},
}; };
static grub_bootp_t static void
grub_getbootp_real (void) grub_ieee1275_net_config_real (const char *devpath, char **device, char **path)
{ {
grub_bootp_t packet = grub_malloc (sizeof *packet); struct grub_net_card *card;
char *bootp_response;
grub_ssize_t size;
unsigned int i;
for (i = 0; i < ARRAY_SIZE (bootp_response_properties); i++) /* FIXME: Check that it's the right card. */
if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, FOR_NET_CARDS (card)
bootp_response_properties[i].name, {
&size) >= 0) char *bootp_response;
break; char *cardpath;
char *canon;
if (size < 0) grub_ssize_t size = -1;
return NULL; unsigned int i;
bootp_response = grub_malloc (size); if (card->driver != &ofdriver)
if (grub_ieee1275_get_property (grub_ieee1275_chosen, continue;
bootp_response_properties[i].name,
bootp_response, size, 0) < 0)
return NULL;
grub_memcpy (packet, bootp_response + bootp_response_properties[i].offset, sizeof (*packet)); cardpath = ((struct grub_ofnetcard_data *) card->data)->path;
grub_free (bootp_response); canon = grub_ieee1275_canonicalise_devname (cardpath);
return packet; if (grub_strcmp (devpath, canon) != 0)
{
grub_free (canon);
continue;
}
grub_free (canon);
for (i = 0; i < ARRAY_SIZE (bootp_response_properties); i++)
if (grub_ieee1275_get_property_length (grub_ieee1275_chosen,
bootp_response_properties[i].name,
&size) >= 0)
break;
if (size < 0)
return;
bootp_response = grub_malloc (size);
if (!bootp_response)
{
grub_print_error ();
return;
}
if (grub_ieee1275_get_property (grub_ieee1275_chosen,
bootp_response_properties[i].name,
bootp_response, size, 0) < 0)
return;
grub_net_configure_by_dhcp_ack (card->name, card, 0,
(struct grub_net_bootp_packet *)
&bootp_response
+ bootp_response_properties[i].offset,
size - bootp_response_properties[i].offset,
1, device, path);
return;
}
}
static char *
find_alias (const char *fullname)
{
char *ret = NULL;
auto int find_alias_hook (struct grub_ieee1275_devalias *alias);
int find_alias_hook (struct grub_ieee1275_devalias *alias)
{
if (grub_strcmp (alias->path, fullname) == 0)
{
ret = grub_strdup (alias->name);
return 1;
}
return 0;
}
grub_devalias_iterate (find_alias_hook);
grub_errno = GRUB_ERR_NONE;
return ret;
} }
static void static void
grub_ofnet_findcards (void) grub_ofnet_findcards (void)
{ {
int i = 0;
auto int search_net_devices (struct grub_ieee1275_devalias *alias); auto int search_net_devices (struct grub_ieee1275_devalias *alias);
int search_net_devices (struct grub_ieee1275_devalias *alias) int search_net_devices (struct grub_ieee1275_devalias *alias)
@ -155,6 +208,7 @@ grub_ofnet_findcards (void)
struct grub_net_card *card; struct grub_net_card *card;
grub_ieee1275_phandle_t devhandle; grub_ieee1275_phandle_t devhandle;
grub_net_link_level_address_t lla; grub_net_link_level_address_t lla;
char *shortname;
ofdata = grub_malloc (sizeof (struct grub_ofnetcard_data)); ofdata = grub_malloc (sizeof (struct grub_ofnetcard_data));
if (!ofdata) if (!ofdata)
@ -162,7 +216,7 @@ grub_ofnet_findcards (void)
grub_print_error (); grub_print_error ();
return 1; return 1;
} }
card = grub_malloc (sizeof (struct grub_net_card)); card = grub_zalloc (sizeof (struct grub_net_card));
if (!card) if (!card)
{ {
grub_free (ofdata); grub_free (ofdata);
@ -177,11 +231,19 @@ grub_ofnet_findcards (void)
if (grub_ieee1275_get_integer_property if (grub_ieee1275_get_integer_property
(devhandle, "max-frame-size", &(ofdata->mtu), (devhandle, "max-frame-size", &(ofdata->mtu),
sizeof (ofdata->mtu), 0)) sizeof (ofdata->mtu), 0))
return grub_error (GRUB_ERR_IO, "Couldn't retrieve mtu size."); {
ofdata->mtu = 1500;
}
if (grub_ieee1275_get_property if (grub_ieee1275_get_property (devhandle, "mac-address",
(devhandle, "mac-address", &(lla.mac), 6, 0)) &(lla.mac), 6, 0)
return grub_error (GRUB_ERR_IO, "Couldn't retrieve mac address."); && grub_ieee1275_get_property (devhandle, "local-mac-address",
&(lla.mac), 6, 0))
{
grub_error (GRUB_ERR_IO, "Couldn't retrieve mac address.");
grub_print_error ();
return 0;
}
lla.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; lla.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
card->default_address = lla; card->default_address = lla;
@ -189,7 +251,11 @@ grub_ofnet_findcards (void)
card->driver = NULL; card->driver = NULL;
card->data = ofdata; card->data = ofdata;
card->flags = 0; card->flags = 0;
card->name = grub_xasprintf ("eth%d", i++); shortname = find_alias (alias->path);
card->name = grub_xasprintf ("ofnet_%s", shortname ? : alias->path);
grub_free (shortname);
card->driver = &ofdriver;
grub_net_card_register (card); grub_net_card_register (card);
return 0; return 0;
} }
@ -200,69 +266,18 @@ grub_ofnet_findcards (void)
grub_ieee1275_devices_iterate (search_net_devices); grub_ieee1275_devices_iterate (search_net_devices);
} }
static void
grub_ofnet_probecards (void)
{
struct grub_net_card *card;
struct grub_net_card_driver *driver;
struct grub_net_network_level_interface *inter;
grub_bootp_t bootp_pckt;
grub_net_network_level_address_t addr;
grub_net_network_level_netaddress_t net;
bootp_pckt = grub_getbootp ();
/* Assign correspondent driver for each device. */
FOR_NET_CARDS (card)
{
FOR_NET_CARD_DRIVERS (driver)
{
if (driver->init (card) == GRUB_ERR_NONE)
{
card->driver = driver;
if (bootp_pckt
&& grub_memcmp (bootp_pckt->chaddr, card->default_address.mac, 6) == 0)
{
addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
addr.ipv4 = bootp_pckt->yiaddr;
grub_net_add_addr ("bootp_cli_addr", card, addr,
card->default_address, 0);
FOR_NET_NETWORK_LEVEL_INTERFACES (inter)
if (grub_strcmp (inter->name, "bootp_cli_addr") == 0)
break;
net.type = addr.type;
net.ipv4.base = addr.ipv4;
net.ipv4.masksize = 24;
grub_net_add_route ("bootp-router", net, inter);
}
break;
}
}
}
grub_free (bootp_pckt);
}
GRUB_MOD_INIT(ofnet) GRUB_MOD_INIT(ofnet)
{ {
struct grub_net_card *card;
grub_getbootp = grub_getbootp_real;
grub_net_card_driver_register (&ofdriver);
grub_ofnet_findcards (); grub_ofnet_findcards ();
grub_ofnet_probecards (); grub_ieee1275_net_config = grub_ieee1275_net_config_real;
FOR_NET_CARDS (card)
if (card->driver == NULL)
grub_net_card_unregister (card);
} }
GRUB_MOD_FINI(ofnet) GRUB_MOD_FINI(ofnet)
{ {
struct grub_net_card *card; struct grub_net_card *card, *next;
FOR_NET_CARDS (card)
if (card->driver && !grub_strcmp (card->driver->name, "ofnet")) FOR_NET_CARDS_SAFE (card, next)
{ if (card->driver && grub_strcmp (card->driver->name, "ofnet") == 0)
card->driver->fini (card); grub_net_card_unregister (card);
card->driver = NULL; grub_ieee1275_net_config = 0;
}
grub_net_card_driver_unregister (&ofdriver);
grub_getbootp = NULL;
} }

View file

@ -25,7 +25,15 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf,
grub_memcpy (eth->src, inf->hwaddress.mac, 6); grub_memcpy (eth->src, inf->hwaddress.mac, 6);
eth->type = grub_cpu_to_be16 (ethertype); eth->type = grub_cpu_to_be16 (ethertype);
if (!inf->card->opened)
{
err = GRUB_ERR_NONE;
if (inf->card->driver->open)
err = inf->card->driver->open (inf->card);
if (err)
return err;
inf->card->opened = 1;
}
return inf->card->driver->send (inf->card, nb); return inf->card->driver->send (inf->card, nb);
} }

View file

@ -30,6 +30,7 @@
#include <grub/term.h> #include <grub/term.h>
#include <grub/net/ethernet.h> #include <grub/net/ethernet.h>
#include <grub/datetime.h> #include <grub/datetime.h>
#include <grub/loader.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -58,6 +59,7 @@ static struct grub_fs grub_net_fs;
static inline void static inline void
grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter)
{ {
inter->card->num_ifaces--;
*inter->prev = inter->next; *inter->prev = inter->next;
if (inter->next) if (inter->next)
inter->next->prev = inter->prev; inter->next->prev = inter->prev;
@ -65,6 +67,24 @@ grub_net_network_level_interface_unregister (struct grub_net_network_level_inter
inter->prev = 0; inter->prev = 0;
} }
void
grub_net_card_unregister (struct grub_net_card *card)
{
struct grub_net_network_level_interface *inf, *next;
FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE(inf, next)
if (inf->card == card)
grub_net_network_level_interface_unregister (inf);
if (card->opened)
{
if (card->driver->close)
card->driver->close (card);
card->opened = 0;
}
grub_list_remove (GRUB_AS_LIST_P (&grub_net_cards),
GRUB_AS_LIST (card));
}
static inline void static inline void
grub_net_route_register (struct grub_net_route *route) grub_net_route_register (struct grub_net_route *route)
{ {
@ -336,6 +356,7 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa
grub_register_variable_hook (name, 0, addr_set_env); grub_register_variable_hook (name, 0, addr_set_env);
} }
inter->card->num_ifaces++;
inter->prev = &grub_net_network_level_interfaces; inter->prev = &grub_net_network_level_interfaces;
inter->next = grub_net_network_level_interfaces; inter->next = grub_net_network_level_interfaces;
if (inter->next) if (inter->next)
@ -345,7 +366,7 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa
struct grub_net_network_level_interface * struct grub_net_network_level_interface *
grub_net_add_addr (const char *name, grub_net_add_addr (const char *name,
const struct grub_net_card *card, struct grub_net_card *card,
grub_net_network_level_address_t addr, grub_net_network_level_address_t addr,
grub_net_link_level_address_t hwaddress, grub_net_link_level_address_t hwaddress,
grub_net_interface_flags_t flags) grub_net_interface_flags_t flags)
@ -714,6 +735,20 @@ grub_net_fs_close (grub_file_t file)
static void static void
receive_packets (struct grub_net_card *card) receive_packets (struct grub_net_card *card)
{ {
if (card->num_ifaces == 0)
return;
if (!card->opened)
{
grub_err_t err = GRUB_ERR_NONE;
if (card->driver->open)
err = card->driver->open (card);
if (err)
{
grub_errno = GRUB_ERR_NONE;
return;
}
card->opened = 1;
}
while (1) while (1)
{ {
/* Maybe should be better have a fixed number of packets for each card /* Maybe should be better have a fixed number of packets for each card
@ -926,7 +961,7 @@ parse_dhcp_vendor (const char *name, void *vend, int limit)
struct grub_net_network_level_interface * struct grub_net_network_level_interface *
grub_net_configure_by_dhcp_ack (const char *name, grub_net_configure_by_dhcp_ack (const char *name,
const struct grub_net_card *card, struct grub_net_card *card,
grub_net_interface_flags_t flags, grub_net_interface_flags_t flags,
const struct grub_net_bootp_packet *bp, const struct grub_net_bootp_packet *bp,
grub_size_t size, grub_size_t size,
@ -1042,7 +1077,7 @@ grub_net_configure_by_dhcp_ack (const char *name,
void void
grub_net_process_dhcp (struct grub_net_buff *nb, grub_net_process_dhcp (struct grub_net_buff *nb,
const struct grub_net_card *card) struct grub_net_card *card)
{ {
char *name; char *name;
struct grub_net_network_level_interface *inf; struct grub_net_network_level_interface *inf;
@ -1228,6 +1263,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)),
if (j) if (j)
ifaces[j].prev = &ifaces[j-1].next; ifaces[j].prev = &ifaces[j-1].next;
ifaces[j].name = grub_xasprintf ("%s:dhcp_tmp", card->name); ifaces[j].name = grub_xasprintf ("%s:dhcp_tmp", card->name);
card->num_ifaces++;
if (!ifaces[j].name) if (!ifaces[j].name)
{ {
unsigned i; unsigned i;
@ -1331,6 +1367,29 @@ static struct grub_fs grub_net_fs =
.uuid = NULL, .uuid = NULL,
.mtime = NULL, .mtime = NULL,
}; };
static grub_err_t
grub_net_fini_hw (int noreturn __attribute__ ((unused)))
{
struct grub_net_card *card;
FOR_NET_CARDS (card)
if (card->opened)
{
if (card->driver->close)
card->driver->close (card);
card->opened = 0;
}
return GRUB_ERR_NONE;
}
static grub_err_t
grub_net_restore_hw (void)
{
return GRUB_ERR_NONE;
}
static void *fini_hnd;
static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute;
static grub_command_t cmd_lsroutes, cmd_lscards, cmd_getdhcp, cmd_bootp; static grub_command_t cmd_lsroutes, cmd_lscards, cmd_getdhcp, cmd_bootp;
static grub_command_t cmd_dhcp, cmd_lsaddr; static grub_command_t cmd_dhcp, cmd_lsaddr;
@ -1367,6 +1426,11 @@ GRUB_MOD_INIT(net)
grub_fs_register (&grub_net_fs); grub_fs_register (&grub_net_fs);
grub_net_open = grub_net_open_real; grub_net_open = grub_net_open_real;
fini_hnd = grub_loader_register_preboot_hook (grub_net_fini_hw,
grub_net_restore_hw,
GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK);
grub_net_fini_hw (0);
grub_loader_unregister_preboot_hook (fini_hnd);
} }
GRUB_MOD_FINI(net) GRUB_MOD_FINI(net)
@ -1381,4 +1445,5 @@ GRUB_MOD_FINI(net)
grub_unregister_command (cmd_getdhcp); grub_unregister_command (cmd_getdhcp);
grub_fs_unregister (&grub_net_fs); grub_fs_unregister (&grub_net_fs);
grub_net_open = NULL; grub_net_open = NULL;
grub_loader_unregister_preboot_hook (fini_hnd);
} }

View file

@ -287,8 +287,6 @@ int EXPORT_FUNC(grub_pxe_call) (int func, void * data, grub_uint32_t pxe_rm_entr
extern struct grub_pxe_bangpxe *grub_pxe_pxenv; extern struct grub_pxe_bangpxe *grub_pxe_pxenv;
void grub_pxe_unload (void);
#endif #endif
#endif /* GRUB_CPU_PXE_H */ #endif /* GRUB_CPU_PXE_H */

View file

@ -64,12 +64,9 @@ struct grub_ieee1275_common_hdr
typedef grub_uint32_t grub_ieee1275_ihandle_t; typedef grub_uint32_t grub_ieee1275_ihandle_t;
typedef grub_uint32_t grub_ieee1275_phandle_t; typedef grub_uint32_t grub_ieee1275_phandle_t;
struct grub_ofnetcard_data extern void (*EXPORT_VAR(grub_ieee1275_net_config)) (const char *dev,
{ char **device,
char *path; char **path);
grub_ieee1275_ihandle_t handle;
grub_uint32_t mtu;
};
/* Maps a device alias to a pathname. */ /* Maps a device alias to a pathname. */
extern grub_ieee1275_phandle_t EXPORT_VAR(grub_ieee1275_chosen); extern grub_ieee1275_phandle_t EXPORT_VAR(grub_ieee1275_chosen);
@ -203,5 +200,6 @@ int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook)
alias)); alias));
char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path); char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path);
char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path); char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path);
char *EXPORT_FUNC(grub_ieee1275_get_device_type) (const char *path);
#endif /* ! GRUB_IEEE1275_HEADER */ #endif /* ! GRUB_IEEE1275_HEADER */

View file

@ -1,66 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2007 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_OFNET_HEADER
#define GRUB_OFNET_HEADER 1
#include <grub/symbol.h>
#include <grub/err.h>
#include <grub/types.h>
struct grub_ofnet
{
/* The net name. */
const char *name;
/* The OF device string. */
char *dev;
/*server ip*/
char *sip;
/*client ip*/
char *cip;
/*gateway*/
char *gat;
/**/
int type;
};
typedef struct grub_ofnet *grub_ofnet_t;
struct grub_bootp {
grub_uint8_t op; /* 1 = BOOTREQUEST, 2 = BOOTREPLY */
grub_uint8_t htype; /* Hardware address type. */
grub_uint8_t hlen; /* Hardware address length */
grub_uint8_t hops; /* Used by gateways in cross-gateway booting. */
grub_uint32_t xid; /* Transaction ID */
grub_uint16_t secs; /* Seconds elapsed. */
grub_uint16_t unused; /* Unused. */
grub_uint32_t ciaddr; /* Client IP address, */
grub_uint32_t yiaddr; /* Client IP address filled by server. */
grub_uint32_t siaddr; /* Server IP address. */
grub_uint32_t giaddr; /* Gateway IP address. */
unsigned char chaddr [16]; /* Client hardware address */
char sname [64]; /* Server name */
char file [128]; /* Boot filename */
unsigned char vend [64];
};
typedef struct grub_bootp* grub_bootp_t;
extern grub_bootp_t (*EXPORT_VAR (grub_getbootp)) (void);
#endif /* ! GRUB_NET_HEADER */

View file

@ -60,6 +60,8 @@ struct grub_net_card_driver
{ {
struct grub_net_card_driver *next; struct grub_net_card_driver *next;
char *name; char *name;
grub_err_t (*open) (const struct grub_net_card *dev);
void (*close) (const struct grub_net_card *dev);
grub_err_t (*send) (const struct grub_net_card *dev, grub_err_t (*send) (const struct grub_net_card *dev,
struct grub_net_buff *buf); struct grub_net_buff *buf);
grub_ssize_t (*recv) (const struct grub_net_card *dev, grub_ssize_t (*recv) (const struct grub_net_card *dev,
@ -87,6 +89,8 @@ struct grub_net_card
struct grub_net_card_driver *driver; struct grub_net_card_driver *driver;
grub_net_link_level_address_t default_address; grub_net_link_level_address_t default_address;
grub_net_card_flags_t flags; grub_net_card_flags_t flags;
int num_ifaces;
int opened;
union union
{ {
struct struct
@ -236,7 +240,7 @@ struct grub_net_network_level_interface
struct grub_net_network_level_interface *next; struct grub_net_network_level_interface *next;
struct grub_net_network_level_interface **prev; struct grub_net_network_level_interface **prev;
char *name; char *name;
const struct grub_net_card *card; struct grub_net_card *card;
grub_net_network_level_address_t address; grub_net_network_level_address_t address;
grub_net_link_level_address_t hwaddress; grub_net_link_level_address_t hwaddress;
grub_net_interface_flags_t flags; grub_net_interface_flags_t flags;
@ -284,7 +288,7 @@ grub_net_session_recv (struct grub_net_session *session, void *buf,
struct grub_net_network_level_interface * struct grub_net_network_level_interface *
grub_net_add_addr (const char *name, grub_net_add_addr (const char *name,
const struct grub_net_card *card, struct grub_net_card *card,
grub_net_network_level_address_t addr, grub_net_network_level_address_t addr,
grub_net_link_level_address_t hwaddress, grub_net_link_level_address_t hwaddress,
grub_net_interface_flags_t flags); grub_net_interface_flags_t flags);
@ -321,12 +325,8 @@ grub_net_card_register (struct grub_net_card *card)
GRUB_AS_LIST (card)); GRUB_AS_LIST (card));
} }
static inline void void
grub_net_card_unregister (struct grub_net_card *card) grub_net_card_unregister (struct grub_net_card *card);
{
grub_list_remove (GRUB_AS_LIST_P (&grub_net_cards),
GRUB_AS_LIST (card));
}
#define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next) #define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next)
#define FOR_NET_CARDS_SAFE(var, next) for (var = grub_net_cards, next = var->next; var; var = next, next = var->next) #define FOR_NET_CARDS_SAFE(var, next) for (var = grub_net_cards, next = var->next; var; var = next, next = var->next)
@ -390,7 +390,7 @@ struct grub_net_bootp_packet
struct grub_net_network_level_interface * struct grub_net_network_level_interface *
grub_net_configure_by_dhcp_ack (const char *name, grub_net_configure_by_dhcp_ack (const char *name,
const struct grub_net_card *card, struct grub_net_card *card,
grub_net_interface_flags_t flags, grub_net_interface_flags_t flags,
const struct grub_net_bootp_packet *bp, const struct grub_net_bootp_packet *bp,
grub_size_t size, grub_size_t size,
@ -398,7 +398,7 @@ grub_net_configure_by_dhcp_ack (const char *name,
void void
grub_net_process_dhcp (struct grub_net_buff *nb, grub_net_process_dhcp (struct grub_net_buff *nb,
const struct grub_net_card *card); struct grub_net_card *card);
int int
grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a,
@ -418,6 +418,8 @@ grub_net_addr_to_str (const grub_net_network_level_address_t *target,
extern struct grub_net_network_level_interface *grub_net_network_level_interfaces; extern struct grub_net_network_level_interface *grub_net_network_level_interfaces;
#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) #define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next)
#define FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE(var,next) for (var = grub_net_network_level_interfaces, next = var->next; var; var = next, next = var->next)
grub_err_t grub_net_send_link_layer (struct grub_net_network_level_interface *inf, grub_err_t grub_net_send_link_layer (struct grub_net_network_level_interface *inf,
struct grub_net_buff *nb, struct grub_net_buff *nb,
grub_net_link_level_address_t *target); grub_net_link_level_address_t *target);