From: Josef Bacik <jbacik@fb.com>
To: Andrei Borzenkov <arvidjaar@gmail.com>
Cc: grub-devel@gnu.org, mchang@suse.com
Subject: Re: [PATCH 3/3] net: fix ipv6 routing
Date: Mon, 10 Aug 2015 10:00:09 -0400 [thread overview]
Message-ID: <55C8AE69.8000201@fb.com> (raw)
In-Reply-To: <20150809175828.73d61027@opensuse.site>
On 08/09/2015 10:58 AM, Andrei Borzenkov wrote:
> В Wed, 5 Aug 2015 14:36:39 -0400
> Josef Bacik <jbacik@fb.com> пишет:
>
>> Currently we cannot talk to ipv6 addresses outside of our local link area
>> because we don't setup our routes properly nor do we talk to the router
>> properly. Currently net_ipv6_autoconf adds routes for the local link prefix and
>> ties it to the global link device. This isn't helpful at all, we completely
>> drop the router part of the router advertisement. So instead create a "default
>> route" flag in routes and create a new route with the local link prefix and the
>> router source address.
>>
>
> Note that RA does not always mean default route. You need to check
> router lifetime to decide whether to use it as default route.
I've been reading the spec a lot recently and I couldn't figure out a
way to differentiate between a default route and just another route.
From my reading if we get multipe RA's we're supposed to just round
robin through them until we get the one that works, obviously taking
into account when the router lifetime expires and such. We don't take
into account the lifetime at all except to see if it is set to 0,
otherwise we never expire anything. We should probably build this out
in the future, but for now just picking whichever router comes first as
the default route will work most of the time.
>
>> The second part of this problem is that the routing code thinks in ipv4 terms,
>> so it expects to find a route to the address we're looking for in our routing
>> table. If we find a gateway then we just look for which interface matches the
>> network for the gateway. This doesn't work for ipv6 since the router gives us
>> its local link address, so the gateway will find the local link interface,
>> instead of the global interface. So to deal with this do a few things
>>
>
> I am afraid it cannot be solved on routing table level. We need to bite
> the bullet and add notion of interface zone and associate each link
> local IPv6 address with interface it comes from (or sent to). This
> automatically solves also the problem in your other patch as well as
> this one by eliminating need to (attempt to) route link local in the
> first place - it is simply sent to interface it is associated with.
>
> It also means we probably need to support IPv6%scope notation for
> addresses.
I'll try and work something out that is better than this patch.
>
>> 1) Create a new "default route" flag for any router advertisements we get when
>> doing the ipv6 autoconf stuff. Then we create a normal gateway route with the
>> default route flag set.
>>
>> 2) When looking for routes keep track of any default routes we find, and if we
>> don't find an exact route that matches we use the default route, which will set
>> the gateway to the router, and then we will find the local link interface that
>> matches this router.
>>
>> 3) Translate the local link interface to the global link interface. We build
>> the ip packets based on the address on the interface, and this needs to have the
>> global address, not the local one. So loop through our interfaces until we find
>> a global address with the same hwaddress as the local link interface and use
>> that instead. This way we get the right addresses on our IP packets.
>>
>
> If I read RFC6724 correctly, we actually must prefer link-local
> source address when speaking with link-local destination.
Right if we're talking to a link-local destination, but when talking to
a global link destination the format is
src-ip: global address for the interface
dst-ip: global address for destination
src-mac: our mac
dst-mac: the mac of the default route
Which is why I did that weird translation.
>
>> With this patch I can now do net_ipv6_autoconf and immediately talk to ipv6
>> addresses outside of my local network. Thanks,
>>
>> Signed-off-by: Josef Bacik <jbacik@fb.com>
>> ---
>> grub-core/net/bootp.c | 2 +-
>> grub-core/net/drivers/ieee1275/ofnet.c | 2 +-
>> grub-core/net/icmp6.c | 50 ++++++++++------------
>> grub-core/net/net.c | 76 +++++++++++++++++++++-------------
>> include/grub/net.h | 28 ++++++++++++-
>> 5 files changed, 99 insertions(+), 59 deletions(-)
>>
> ...
>> diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c
>> index 7953e68..fad04a9 100644
>> --- a/grub-core/net/icmp6.c
>> +++ b/grub-core/net/icmp6.c
>> @@ -373,7 +373,10 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
>> if (ohdr->type == OPTION_PREFIX && ohdr->len == 4)
>> {
>> struct prefix_option *opt = (struct prefix_option *) ptr;
>> + struct grub_net_route *route;
>> struct grub_net_slaac_mac_list *slaac;
>> +
>> + grub_net_network_level_netaddress_t netaddr;
>> if (!(opt->flags & FLAG_SLAAC)
>> || (grub_be_to_cpu64 (opt->prefix[0]) >> 48) == 0xfe80
>> || (grub_be_to_cpu32 (opt->preferred_lifetime)
>> @@ -391,18 +394,12 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
>> for (slaac = card->slaac_list; slaac; slaac = slaac->next)
>> {
>> grub_net_network_level_address_t addr;
>> - grub_net_network_level_netaddress_t netaddr;
>> -
>> if (slaac->address.type
>> != GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET)
>> continue;
>> addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
>> addr.ipv6[0] = opt->prefix[0];
>> addr.ipv6[1] = grub_net_ipv6_get_id (&slaac->address);
>> - netaddr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
>> - netaddr.ipv6.base[0] = opt->prefix[0];
>> - netaddr.ipv6.base[1] = 0;
>> - netaddr.ipv6.masksize = 64;
>>
>> FOR_NET_NETWORK_LEVEL_INTERFACES (inf)
>> {
>> @@ -410,29 +407,28 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
>> && grub_net_addr_cmp (&inf->address, &addr) == 0)
>> break;
>> }
>> - /* Update lease time if needed here once we have
>> - lease times. */
>> - if (inf)
>> - continue;
>> + if (!inf)
>> + slaac->slaac_counter++;
>> + }
>>
>> - grub_dprintf ("net", "creating slaac\n");
>> + netaddr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
>> + netaddr.ipv6.base[0] = opt->prefix[0];
>> + netaddr.ipv6.base[1] = 0;
>> + netaddr.ipv6.masksize = 64;
>>
>> - {
>> - char *name;
>> - name = grub_xasprintf ("%s:%d",
>> - slaac->name, slaac->slaac_counter++);
>> - if (!name)
>> - {
>> - grub_errno = GRUB_ERR_NONE;
>> - continue;
>> - }
>> - inf = grub_net_add_addr (name,
>> - card, &addr,
>> - &slaac->address, 0);
>> - grub_net_add_route (name, netaddr, inf);
>> - grub_free (name);
>> - }
>> - }
>
> This kills SLAAC. Where global addresses now come from? You probably
> get them from DHCPv6 but it does not mean we should drop SLAAC.
Eesh I just ripped that out didn't I? Sorry about that, I'll rework
this again. I think I'll do like you said above, just kind of create an
interface with different scopes and that way if you use both slaac and
dhcp and get the same address we don't end up with two different
interfaces. And then I'll come up with something to tie the routers to
the interfaces and rework the route stuff so it is a bit cleaner. This
will probably be towards the end of the week, I've found some weird
timeout problem in the TCP stack I'm trying to track down, once I've
figured that out I'll rework this patch. Thanks,
Josef
next prev parent reply other threads:[~2015-08-10 14:00 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-05 18:36 [PATCH 1/3] efinet: handle get_status() properly Josef Bacik
2015-08-05 18:36 ` [PATCH 2/3] net: add local route when creating link local ipv6 interface Josef Bacik
2015-08-07 8:38 ` Andrei Borzenkov
2015-08-05 18:36 ` [PATCH 3/3] net: fix ipv6 routing Josef Bacik
2015-08-09 14:58 ` Andrei Borzenkov
2015-08-10 14:00 ` Josef Bacik [this message]
2015-08-10 14:07 ` Andrei Borzenkov
2015-08-05 20:04 ` [PATCH 1/3] efinet: handle get_status() properly Andrei Borzenkov
2015-08-05 20:26 ` Josef Bacik
2015-08-05 20:32 ` Vladimir 'phcoder' Serbinenko
2015-08-05 20:39 ` Josef Bacik
2015-08-05 20:50 ` Josef Bacik
2015-08-05 20:52 ` Vladimir 'phcoder' Serbinenko
2015-08-06 3:42 ` Andrei Borzenkov
2015-08-06 14:26 ` Josef Bacik
2015-08-05 20:57 ` Seth Goldberg
2015-08-06 17:49 ` [PATCH V2] efinet: handle get_status() on buggy firmware properly Josef Bacik
2015-08-09 13:48 ` Andrei Borzenkov
-- strict thread matches above, loose matches on Subject: below --
2015-08-05 17:50 [PATCH 0/3] fix ipv6 support Josef Bacik
2015-08-05 17:50 ` [PATCH 3/3] net: fix ipv6 routing Josef Bacik
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55C8AE69.8000201@fb.com \
--to=jbacik@fb.com \
--cc=arvidjaar@gmail.com \
--cc=grub-devel@gnu.org \
--cc=mchang@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.