I don't have EFI spec under my hand now. Can we get away with making it a default or at least for the case when no interface overrides mac address. Extra config to workaround firmware bugs is usually harmful Le 5 nov. 2015 9:17 PM, "Josef Bacik" <jba...@fb.com> a écrit :
> We have some hardware that doesn't honor > EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST properly so we aren't > getting > RA's that are multicasted properly (our switches respond to solicitations > with a > multicast rather than a unicast). I don't want to add this filtering by > default, so add a new command to allow a user to specify a multicast > receive > filter. We use it like this > > efinet_multicast_filter efinet0 33:33:0:0:0:1 > > to get ipv6 multicasts which allows us to receive the router > advertisements. > Thanks, > > Signed-off-by: Josef Bacik <jba...@fb.com> > --- > grub-core/kern/efi/efi.c | 12 ++++----- > grub-core/net/drivers/efi/efinet.c | 51 > ++++++++++++++++++++++++++++++++++++++ > grub-core/net/net.c | 43 ++++++++++++++++++++++++++++++++ > include/grub/efi/api.h | 5 +++- > include/grub/net.h | 3 +++ > 5 files changed, 107 insertions(+), 7 deletions(-) > > diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c > index 2e77834..efc3d33 100644 > --- a/grub-core/kern/efi/efi.c > +++ b/grub-core/kern/efi/efi.c > @@ -652,12 +652,12 @@ grub_efi_print_device_path (grub_efi_device_path_t > *dp) > grub_efi_mac_address_device_path_t *mac > = (grub_efi_mac_address_device_path_t *) dp; > grub_printf ("/MacAddr(%02x:%02x:%02x:%02x:%02x:%02x,%x)", > - (unsigned) mac->mac_address[0], > - (unsigned) mac->mac_address[1], > - (unsigned) mac->mac_address[2], > - (unsigned) mac->mac_address[3], > - (unsigned) mac->mac_address[4], > - (unsigned) mac->mac_address[5], > + (unsigned) mac->mac_address.addr[0], > + (unsigned) mac->mac_address.addr[1], > + (unsigned) mac->mac_address.addr[2], > + (unsigned) mac->mac_address.addr[3], > + (unsigned) mac->mac_address.addr[4], > + (unsigned) mac->mac_address.addr[5], > (unsigned) mac->if_type); > } > break; > diff --git a/grub-core/net/drivers/efi/efinet.c > b/grub-core/net/drivers/efi/efinet.c > index c8f80a1..8c2c4f8 100644 > --- a/grub-core/net/drivers/efi/efinet.c > +++ b/grub-core/net/drivers/efi/efinet.c > @@ -23,6 +23,7 @@ > #include <grub/efi/api.h> > #include <grub/efi/efi.h> > #include <grub/i18n.h> > +#include <grub/command.h> > > GRUB_MOD_LICENSE ("GPLv3+"); > > @@ -451,9 +452,58 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char > **device, > } > } > > +static grub_err_t > +grub_cmd_multicast_filter (struct grub_command *cmd __attribute__ > ((unused)), > + int argc, char **args) > +{ > + struct grub_net_card *card; > + grub_efi_simple_network_t *net; > + grub_net_link_level_address_t hwaddr; > + grub_efi_mac_address_t filter_mac[1]; > + grub_efi_status_t st; > + > + if (argc != 2) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments > expected")); > + > + FOR_NET_CARDS (card) > + if (grub_strcmp (card->name, args[0]) == 0) > + break; > + > + if (card == NULL) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("card not found")); > + if (card->driver != &efidriver) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("card not an efi card")); > + > + if (grub_net_str_to_hwaddr (args[1], &hwaddr) == 0) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("couldn't parse hw > address")); > + grub_memset (filter_mac, 0, sizeof(filter_mac)); > + grub_memcpy (filter_mac, hwaddr.mac, 6); > + > + net = card->efi_net; > + if (!(net->mode->receive_filter_mask & > + GRUB_EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST)) > + return grub_error (GRUB_ERR_IO, > + N_("device doesn't support multicast filtering")); > + > + st = efi_call_6 (net->receive_filters, net, > + GRUB_EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST, 0, 0, 1, > + filter_mac); > + if (st != GRUB_EFI_SUCCESS) > + return grub_error (GRUB_ERR_IO, > + N_("could not set multicast filter address")); > + > + return GRUB_ERR_NONE; > +} > + > +static grub_command_t cmd_multicast_filter; > + > GRUB_MOD_INIT(efinet) > { > grub_efinet_findcards (); > + cmd_multicast_filter = grub_register_command ("efinet_multicast_filter", > + grub_cmd_multicast_filter, > + N_("CARD HWADDRESS"), > + N_("Add a multicast > filter")); > grub_efi_net_config = grub_efi_net_config_real; > } > > @@ -464,5 +514,6 @@ GRUB_MOD_FINI(efinet) > FOR_NET_CARDS_SAFE (card, next) > if (card->driver == &efidriver) > grub_net_card_unregister (card); > + grub_unregister_command(cmd_multicast_filter); > } > > diff --git a/grub-core/net/net.c b/grub-core/net/net.c > index 65bea28..3a69f63 100644 > --- a/grub-core/net/net.c > +++ b/grub-core/net/net.c > @@ -480,6 +480,49 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const > char **rest) > return 1; > } > > +int > +grub_net_str_to_hwaddr (const char *val, grub_net_link_level_address_t > *hwaddr) > +{ > + grub_uint8_t newmac[6]; > + const char *ptr = val; > + int word; > + > + if (ptr[0] == ':' && ptr[1] != ':') > + return 0; > + if (ptr[0] == ':') > + ptr++; > + > + for (word = 0; word < 6; word++) > + { > + unsigned long t; > + if (*ptr == ':') > + { > + word--; > + ptr++; > + continue; > + } > + t = grub_strtoul (ptr, (char **) &ptr, 16); > + if (grub_errno) > + { > + grub_errno = GRUB_ERR_NONE; > + break; > + } > + if (t & ~0xff) > + return 0; > + newmac[word] = t; > + if (*ptr != ':') > + break; > + ptr++; > + } > + if (*ptr != 0) > + return grub_error (GRUB_ERR_NET_BAD_ADDRESS, > + N_("unrecognized link level address '%s'"), > + val); > + hwaddr->type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; > + grub_memcpy (hwaddr->mac, newmac, 6); > + return 1; > +} > + > static int > match_net (const grub_net_network_level_netaddress_t *net, > const grub_net_network_level_address_t *addr) > diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h > index 9a73976..48940be 100644 > --- a/include/grub/efi/api.h > +++ b/include/grub/efi/api.h > @@ -523,7 +523,10 @@ typedef void *grub_efi_handle_t; > typedef void *grub_efi_event_t; > typedef grub_efi_uint64_t grub_efi_lba_t; > typedef grub_efi_uintn_t grub_efi_tpl_t; > -typedef grub_uint8_t grub_efi_mac_address_t[32]; > +typedef struct { > + grub_uint8_t addr[32]; > +} grub_efi_mac_address_t; > + > typedef grub_uint8_t grub_efi_ipv4_address_t[4]; > typedef grub_uint16_t grub_efi_ipv6_address_t[8]; > typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ > ((aligned(4))); > diff --git a/include/grub/net.h b/include/grub/net.h > index a1ff519..12cc1db 100644 > --- a/include/grub/net.h > +++ b/include/grub/net.h > @@ -522,6 +522,9 @@ grub_net_addr_to_str (const > grub_net_network_level_address_t *target, > char *buf); > void > grub_net_hwaddr_to_str (const grub_net_link_level_address_t *addr, char > *str); > +int > +grub_net_str_to_hwaddr (const char *val, > + grub_net_link_level_address_t *hwaddr); > > grub_err_t > grub_env_set_net_property (const char *intername, const char *suffix, > -- > 1.8.1 > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel >
_______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel