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

Reply via email to