[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] send router solicitation for ipv6 address autoconf
From: |
Andrei Borzenkov |
Subject: |
Re: [PATCH] send router solicitation for ipv6 address autoconf |
Date: |
Sat, 15 Nov 2014 19:54:42 +0300 |
В Thu, 13 Nov 2014 17:42:23 +0800
Michael Chang <address@hidden> пишет:
> Many routers have long router advertisment interval configured by
> default. The Neighbor Discovery protocol (RFC4861) has defined default
> MaxRtrAdvInterval value as 600 seconds and
> MinRtrAdvInterval as 0.33*MaxRtrAdvInterval. This makes
> net_ipv6_autoconf fails more often than not as currently it passively
> listens the RA message to perfom address autoconfiguration.
>
> This patch tries to send router solicitation to overcome the problem of
> long RA interval.
> ---
> grub-core/net/icmp6.c | 81
> +++++++++++++++++++++++++++++++++++++++++++++++++
> grub-core/net/net.c | 4 ++-
> include/grub/net/ip.h | 2 +
> 3 files changed, 86 insertions(+), 1 deletions(-)
>
> diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c
> index 796d549..87b264f 100644
> --- a/grub-core/net/icmp6.c
> +++ b/grub-core/net/icmp6.c
> @@ -72,6 +72,11 @@ struct neighbour_advertise
> grub_uint64_t target[2];
> } GRUB_PACKED;
>
> +struct router_solicit
> +{
> + grub_uint32_t reserved;
> +} GRUB_PACKED;
> +
> enum
> {
> FLAG_SLAAC = 0x40
> @@ -81,6 +86,7 @@ enum
> {
> ICMP6_ECHO = 128,
> ICMP6_ECHO_REPLY = 129,
> + ICMP6_ROUTER_SOLICIT = 133,
> ICMP6_ROUTER_ADVERTISE = 134,
> ICMP6_NEIGHBOUR_SOLICIT = 135,
> ICMP6_NEIGHBOUR_ADVERTISE = 136,
> @@ -533,3 +539,78 @@ grub_net_icmp6_send_request (struct
> grub_net_network_level_interface *inf,
> grub_netbuff_free (nb);
> return err;
> }
> +
> +grub_err_t
> +grub_net_icmp6_send_router_solicit (struct grub_net_network_level_interface
> *inf)
> +{
> + struct grub_net_buff *nb;
> + grub_err_t err = GRUB_ERR_NONE;
> + grub_net_network_level_address_t multicast;
> + grub_net_link_level_address_t ll_multicast;
> + struct option_header *ohdr;
> + struct router_solicit *sol;
> + struct icmp_header *icmphr;
> +
> + multicast.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
> + multicast.ipv6[0] = grub_be_to_cpu64_compile_time (0xff02ULL << 48);
> + multicast.ipv6[1] = grub_be_to_cpu64_compile_time (0x02ULL);
> +
Could you use cpu_to_be variant; it makes it less confusing (that is
what we do here).
> + err = grub_net_link_layer_resolve (inf, &multicast, &ll_multicast);
> + if (err)
> + return err;
> +
> + nb = grub_netbuff_alloc (sizeof (struct router_solicit)
> + + sizeof (struct option_header)
> + + 6
> + + sizeof (struct icmp_header)
> + + GRUB_NET_OUR_IPV6_HEADER_SIZE
> + + GRUB_NET_MAX_LINK_HEADER_SIZE);
> + if (!nb)
> + return grub_errno;
> + err = grub_netbuff_reserve (nb,
> + sizeof (struct router_solicit)
> + + sizeof (struct option_header)
> + + 6
> + + sizeof (struct icmp_header)
> + + GRUB_NET_OUR_IPV6_HEADER_SIZE
> + + GRUB_NET_MAX_LINK_HEADER_SIZE);
> +
Error check?
Otherwise personally I'm fine with it.
> + err = grub_netbuff_push (nb, 6);
> + if (err)
> + goto fail;
> +
> + grub_memcpy (nb->data, inf->hwaddress.mac, 6);
> +
> + err = grub_netbuff_push (nb, sizeof (*ohdr));
> + if (err)
> + goto fail;
> +
> + ohdr = (struct option_header *) nb->data;
> + ohdr->type = OPTION_SOURCE_LINK_LAYER_ADDRESS;
> + ohdr->len = 1;
> +
> + err = grub_netbuff_push (nb, sizeof (*sol));
> + if (err)
> + goto fail;
> +
> + sol = (struct router_solicit *) nb->data;
> + sol->reserved = 0;
> +
> + err = grub_netbuff_push (nb, sizeof (*icmphr));
> + if (err)
> + goto fail;
> +
> + icmphr = (struct icmp_header *) nb->data;
> + icmphr->type = ICMP6_ROUTER_SOLICIT;
> + icmphr->code = 0;
> + icmphr->checksum = 0;
> + icmphr->checksum = grub_net_ip_transport_checksum (nb,
> + GRUB_NET_IP_ICMPV6,
> + &inf->address,
> + &multicast);
> + err = grub_net_send_ip_packet (inf, &multicast, &ll_multicast, nb,
> + GRUB_NET_IP_ICMPV6);
> + fail:
> + grub_netbuff_free (nb);
> + return err;
> +}
> diff --git a/grub-core/net/net.c b/grub-core/net/net.c
> index 82af3a0..21a4e94 100644
> --- a/grub-core/net/net.c
> +++ b/grub-core/net/net.c
> @@ -380,12 +380,14 @@ grub_cmd_ipv6_autoconf (struct grub_command *cmd
> __attribute__ ((unused)),
>
> for (interval = 200; interval < 10000; interval *= 2)
> {
> - /* FIXME: send router solicitation. */
> int done = 1;
> for (j = 0; j < ncards; j++)
> {
> if (slaacs[j]->slaac_counter)
> continue;
> + err = grub_net_icmp6_send_router_solicit (ifaces[j]);
> + if (err)
> + err = GRUB_ERR_NONE;
> done = 0;
> }
> if (done)
> diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h
> index 7a8e614..dcceaa5 100644
> --- a/include/grub/net/ip.h
> +++ b/include/grub/net/ip.h
> @@ -92,4 +92,6 @@ grub_err_t
> grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf,
> const grub_net_network_level_address_t
> *proto_addr);
>
> +grub_err_t
> +grub_net_icmp6_send_router_solicit (struct grub_net_network_level_interface
> *inf);
> #endif