Subject: [v6ops] Fwd: New Version Notification for draft-bowbakova-rtgwg-enterprise-pa-multihoming-00.txt

From: "Fred Baker (fred)" <[email-masked]>
Date: Wed, 6 Jul 2016 16:33:18 +0000

At IETF 94, this working group advised the routing ADs and Routing Working Group that PA multihoming would not work without a source/destination routing solution. This draft was developed in response. Routing Working Group requests v6ops review.

> Begin forwarded message:
> 
> From: <[email-masked]>
> Subject: New Version Notification for draft-bowbakova-rtgwg-enterprise-pa-multihoming-00.txt
> Date: July 5, 2016 at 5:58:25 PM PDT
> To: Chris Bowers <[email-masked]>, Jen Linkova <[email-masked]>, "Fred Baker" <[email-masked]>, "J. Linkova" <[email-masked]>
> 
> 
> A new version of I-D, draft-bowbakova-rtgwg-enterprise-pa-multihoming-00.txt
> has been successfully submitted by Fred Baker and posted to the
> IETF repository.
> 
> Name:		draft-bowbakova-rtgwg-enterprise-pa-multihoming
> Revision:	00
> Title:		Enterprise Multihoming using Provider-Assigned Addresses without Network Prefix Translation: Requirements and Solution
> Document date:	2016-07-05
> Group:		Individual Submission
> Pages:		44
> URL:            https://www.ietf.org/internet-drafts/draft-bowbakova-rtgwg-enterprise-pa-multihoming-00.txt
> Status:         https://datatracker.ietf.org/doc/draft-bowbakova-rtgwg-enterprise-pa-multihoming/
> Htmlized:       https://tools.ietf.org/html/draft-bowbakova-rtgwg-enterprise-pa-multihoming-00
> 
> 
> Abstract:
>  Connecting an enterprise site to multiple ISPs using provider-
>  assigned addresses is difficult without the use of some form of
>  Network Address Translation (NAT).  Much has been written on this
>  topic over the last 10 to 15 years, but it still remains a problem
>  without a clearly defined or widely implemented solution.  Any
>  multihoming solution without NAT requires hosts at the site to have
>  addresses from each ISP and to select the egress ISP by selecting a
>  source address for outgoing packets.  It also requires routers at the
>  site to take into account those source addresses when forwarding
>  packets out towards the ISPs.
> 
>  This document attempts to define a complete solution to this problem.
>  It covers the behavior of routers to forward traffic taking into
>  account source address, and it covers the behavior of host to select
>  appropriate source addresses.  It also covers any possible role that
>  routers might play in providing information to hosts to help them
>  select appropriate source addresses.  In the process of exploring
>  potential solutions, this documents also makes explicit requirements
>  for how the solution would be expected to behave from the perspective
>  of an enterprise site network administrator .
> 
> 
> 
> 
> Please note that it may take a couple of minutes from the time of submission
> until the htmlized version and diff are available at tools.ietf.org.
> 
> The IETF Secretariat
>

---

From: Brian E Carpenter <[email-masked]>
Date: Sun, 10 Jul 2016 01:01:44 +1200

Dear Bowbakova,

This is good stuff. We need SADR on site routers.

draft-ietf-6man-multi-homed-host is listed in the references but not cited
in the text. Since it is all about effective use of RFC6724 rule 5.5, I would
expect it to carefully referenced in section 4.1. In fact, the behaviour
specified by draft-ietf-6man-multi-homed-host seems to be essential for
your mechanism to succeed. You almost say that in section 4.2.2 but again
without citing the draft.

Worse, section 4.2.4 says:

>    At the same time Router Advertisements provide a reliable mechanism
>    to influence source address selection process via PIO, RIO and
>    default router preferences.  As all those options have been
>    standardized by IETF and are supported by various operating systems,
>    no changes are required on hosts. 

That's not true. The changes described in draft-ietf-6man-multi-homed-host
*are* required. Also, routers must be capable of sending PIOs with both
L and A bits set to zero.

The same error occurs in section 4.6:

>    1.  no new (non-standard) functionality needs to be implemented on
>        hosts (except for [RFC4191] support);

Section 5.1, shim6. While not disputing your conclusion, I think this is
misleading:

>    We do not consider Shim6 to be a viable solution.  It suffers from
>    the fact that it requires widespread deployment of Shim6 on hosts...

It is a two-ended solution and we always knew that it could only be deployed
incrementally and opportunistically; that was the plan, not a defect. The real
defect is that the Internet is partly opaque to IPv6 extension headers, and
therefore even incremental deployment of shim6 is not viable. (The same goes
for HIP-based multihoming, which you don't mention.)

Finally, it's helpful in site multihoming proposals to indicate whether
they meet the goals in RFC 3582.

Regards
   Brian

On 07/07/2016 04:33, Fred Baker (fred) wrote:
> _______________________________________________
> v6ops mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/v6ops
>

---

From: Jen Linkova <[email-masked]>
Date: Tue, 12 Jul 2016 00:10:19 +0200

Brian,

First of all - thanks for reviewing the draft and providing your feedback!

On Sat, Jul 9, 2016 at 3:01 PM, Brian E Carpenter
<[email-masked]> wrote:
> expect it to carefully referenced in section 4.1.

Ah, good catch, thanks - I'll add the reference.

>In fact, the behaviour
> your mechanism to succeed.

You are right, most of them are required, I'll update the text, thanks
for pointing this out. Looks like we've completely
missed the scenario when hosts have addresses assigned by DHCPv6 (or
manually) and receive RAs...

However I'm not sure about Section 3.2...
draft-ietf-6man-multi-homed-host says:
"Default Router Selection is modified as follows: A host SHOULD select
   default routers for each prefix it is assigned an address in.".

I'm not sure it is actually required if routers implement the feature
described in our draft and send one RA (with PIOs) per
scoped table (as the whole idea of a SADR-capable router pretending to
be two or more routers - one router per scoped table is
to trick the host).
The host SHOULD add a router into its Default Router list upon
receiving a valid RA with non-zero Router Lifetime, yes (as per
RFC4191).
Let's look at the situation when R3 (see Figure 3 at the page 11 of
draft-bowbakova-rtgwg-enterprise-pa-multihoming-00) sends two RAs: one
from LLA_A for its forwarding table scoped to 2001:db8:0:a000::/56 and
another one from LLA_B for its forwarding table scoped to
2001:db8:0:b000::/56.
Even if the first RA has two PIOs (e.g. 2001:db8:0:a020::/64 and
2001:db8:0:a021::/64), the host does not need to select two default
routers for 2001:db8:0:a020::/64 and 2001:db8:0:a021::/64 as it would
not add any functionality (both prefixes will match the same scoped
table on SADR-capable routers). Basically,  if packets with source
addresses from two prefixes are going to be routed differently, then
those two prefixes belong to two different scoped tables on the
network side and therefore two RAs will be sent for them.
Am I missing smth?

>You almost say that in section 4.2.2 but again
> *are* required.

To be honest I'm a bit confused with the changes described in the Section 3.1 of
draft-ietf-6man-multi-homed-host...
Let's assume that
1) first-hop routers behave as described in
draft-bowbakova-rtgwg-enterprise-pa-multihoming-00
(SADR-capable routers which stop advertizing
themselves as default routers and/or withdraw the prefixes if source
address from that prefix should not be used)
2) the host uses the rule 5.5 of the source address selection algorithm.
In that case would not any host which follows RFC6724 and RFC4191
behave exactly as described in the Section 3.1 anyway?
(sorry for the stupid question, I feel like I'm missing smth here..).

The Section 3.2 (Default Router Selection) - see my comment above.

I'll add the reference to the section 3.4 of
draft-ietf-6man-multi-homed-host to the sections of our draft
which discuss ICMPv6 error messages as a mechanism to influence the
address selection on hosts.

> Also, routers must be capable of sending PIOs with both

Oh, I was not consider that as a special feature, assuming any router
should be capable of doing that.
Probably you are right and it should be explicitly mentioned, just in case...

> for HIP-based multihoming, which you don't mention.)

Good point, I'll update the text with extension header issues.

> they meet the goals in RFC 3582.

Oh, thanks - we do list RFC3582  in the Normative References section
but there is no reference to it
in the text. Will be fixed!

-- 
SY, Jen Linkova aka Furry

---

From: Brian E Carpenter <[email-masked]>
Date: Tue, 12 Jul 2016 19:01:27 +1200

Hi,

> be two or more routers - one router per scoped table is

That may be. Fred should comment, but in the 6man draft we were
trying to cover as many cases as possible, while *hoping* that
SADR would become widespread.

> network side and therefore two RAs will be sent for them.

I don't think you are. But today, that doesn't happen, and I think
we were trying to have the host do the best it can anyway.

> (sorry for the stupid question, I feel like I'm missing smth here..).

No, I think that's right, but today many hosts don't use rule 5.5
and many routers don't do SADR. We were trying to make the best of it.

> Probably you are right and it should be explicitly mentioned, just in case...

People have alleged that current routers won't do that.

Thanks!
   Brian

---

From: Jen Linkova <[email-masked]>
Date: Tue, 12 Jul 2016 10:44:15 +0200

> and many routers don't do SADR. We were trying to make the best of it.

Ah, I see, it's more clear now, thanks for the explanation.
So basically the changes described in draft-ietf-6man-multi-homed-host
are required unless the network (and the first-hop routers in particular)
support SADR and the features described in
draft-bowbakova-rtgwg-enterprise-pa-multihoming.

What if the Section 4.2.4 is re-phrased in the following way:
=== old text===

At the same time Router Advertisements provide a reliable mechanism
   to influence source address selection process via PIO, RIO and
   default router preferences.  As all those options have been
   standardized by IETF and are supported by various operating systems,
   no changes are required on hosts.  First-hop routers in the
   enterprise network need to be able of sending different RAs for
   different SLAAC prefixes (either based on scoped forwarding tables or
   based on pre-configured policies).
===== new text =====
At the same time Router Advertisements provide a reliable mechanism
   to influence source address selection process via PIO, RIO and
   default router preferences (all those options have been
   standardized by IETF). In SADR-capable network where first-hop routers
are capable of sending different RAs for different SLAAC prefixes
(either based on scoped forwarding tables or
   based on pre-configured policies), no changes in hosts behavior are
required. However to fully benefit of RA-based solution,
hosts are required to support RFC4191 and use the Rule 5.5 of source
address selection algorithm as specified in RFC6724.
If first-hop routers do not support SADR and scoped RAs as described
in the Section 4 of this document, hosts behavior needs to
be changed as described in draft-ietf-6man-multi-homed-host
======

(Section 4.6 will be updated accordingly).

What do you think?

>From deployment perspective requesting a new feature from my router
vendor(s) and upgrading X (where X < 100 usually) routers is much
simpler than requesting a behavior change of thousands of end devices
(well, some of them might not support Rule 5.5 and RFC4191 but at
least some of them do...), especially in 'Bring Your Own Device'
model.  IMHO it would be nice to make it clear in the document that
SADR helps deploying multihoming with minimal changes on hosts side
(comparing to changes required if the network is not SADR-capable).

> People have alleged that current routers won't do that.

I'll update the text with the requirement, thanks!

---

From: Brian E Carpenter <[email-masked]>
Date: Tue, 12 Jul 2016 21:32:43 +1200

in line...

> (Section 4.6 will be updated accordingly).

That looks good to me, assuming Fred agrees.

Rgds
   Brian

---

From: David Lamparter <[email-masked]>
Date: Wed, 20 Jul 2016 14:54:58 +0200

As mentioned on mic during rtgwg, I think the idea of affecting host
source address selection through 6724 rule 5.5 is potentially very
useful and IMHO should be explored.

Hence, I hacked it up for the Linux (4.5.0) kernel; patches are attached
to this mail.  I've been able to gleam a little more detail on the idea:

- it's a bit unclear how an address/prefix's "source" next-hop is kept
  in association.  The simplistic approach of adding a "PA source ipv6
  address" for each of a host's configured addresses falls flat when
  more than 1 router advertises the same prefix, so I implemented it as
  a list -- however, my hack never removes entries off that.  It should
  possibly have a copy of the PA's valid time?

  (Read as: the "Discussion" note in 6724 is right on the mark - the
  details are not quite specified.)

- in that avenue, I don't think it's possible to store the information
  in a route-centric way, because RA lifetimes tend to be shorter.
  If a router goes away and comes back, it seems to me that the prefix's
  associated origin/nexthop should still be there.

- rule 5.5 makes RA preference carry into source address selection.  I
  think this is described in the draft, I just failed to grasp that from
  the presentation.  Very useful for getting source selection right in
  the face of unequal performance uplinks.

- if you want to manage this in an userspace process on Linux, you can
  simply update the route's preferred source attribute.

The attached patchset also has the following caveats that result from me
just doing a quick hack:
- there is no debugging/user visibility of the value
- as mentioned above, tracked source addresses never go away unless the
  entire address dies.  It caps at 4 sources (so you can't exhaust
  kernel memory by spoofing...)
- I should probably pass Linux's "dst" instead of "rt6_info"
- I didn't check for locking/concurrentness violations
- there's a const warning which I ignored.

Either way if anyone wants to tinker with it, here it is.
No warranties, YMMV.  You touch it, it becomes your responsibility ;)

Cheers,

-David

>From 2d1bf126d3e776deabcab4ef8b6f941636b8bc67 Mon Sep 17 00:00:00 2001
From: David Lamparter <[email-masked]>
Date: Wed, 20 Jul 2016 10:37:54 +0200
Subject: [PATCH 1/3] net/ipv6: track autoconfigured address' origin

---
 include/net/addrconf.h |  3 ++-
 include/net/if_inet6.h | 11 +++++++++++
 net/ipv6/addrconf.c    | 15 ++++++++++++++-
 net/ipv6/ndisc.c       |  3 ++-
 4 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 47f52d3..33f2652 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -226,7 +226,8 @@ static inline bool ipv6_is_mld(struct sk_buff *skb, int nexthdr, int offset)
 }
 
 void addrconf_prefix_rcv(struct net_device *dev,
-			 u8 *opt, int len, bool sllao);
+			 u8 *opt, int len, bool sllao,
+			 const struct in6_addr *source);
 
 /*
  *	anycast prototypes (anycast.c)
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 1c8b682..f79faa9 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -38,6 +38,14 @@ enum {
 	INET6_IFADDR_STATE_DEAD,
 };
 
+/* for RFC6724 rule 5.5, we want to know what router advertised a prefix;
+ * however, there may be multiple such routers, so it needs to be a list.
+ * (think redundant default gateways)
+ *
+ * to prevent spoofed packets filling memory - and to keep this simple -
+ * this is a fixed-size list. */
+#define INET6_IFADDR_ORIGINRTR_MAX	4
+
 struct inet6_ifaddr {
 	struct in6_addr		addr;
 	__u32			prefix_len;
@@ -75,6 +83,9 @@ struct inet6_ifaddr {
 
 	struct rcu_head		rcu;
 	struct in6_addr		peer_addr;
+
+	size_t			origin_rtr_count;
+	struct in6_addr		origin_rtr[INET6_IFADDR_ORIGINRTR_MAX];
 };
 
 struct ip6_sf_socklist {
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index fd065f2..f148278 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2338,7 +2338,19 @@ static bool is_addr_mode_generate_stable(struct inet6_dev *idev)
 	       idev->addr_gen_mode == IN6_ADDR_GEN_MODE_RANDOM;
 }
 
-void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
+static void addr_register_origin(struct inet6_ifaddr *addr,
+				 const struct in6_addr *rtr)
+{
+	if (!rtr)
+		return;
+	if (addr->origin_rtr_count == ARRAY_SIZE(addr->origin_rtr))
+		return;
+	addr->origin_rtr[addr->origin_rtr_count] = *rtr;
+	addr->origin_rtr_count++;
+}
+
+void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao,
+			 const struct in6_addr *source)
 {
 	struct prefix_info *pinfo;
 	__u32 valid_lft;
@@ -2556,6 +2568,7 @@ ok:
 			in6_ifa_put(ifp);
 			addrconf_verify();
 		}
+		addr_register_origin(ifp, source);
 	}
 	inet6_prefix_notify(RTM_NEWPREFIX, in6_dev, pinfo);
 	in6_dev_put(in6_dev);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 84afb9a..b298da6 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1385,7 +1385,8 @@ skip_routeinfo:
 		     p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
 			addrconf_prefix_rcv(skb->dev, (u8 *)p,
 					    (p->nd_opt_len) << 3,
-					    ndopts.nd_opts_src_lladdr != NULL);
+					    ndopts.nd_opts_src_lladdr != NULL,
+					    &ipv6_hdr(skb)->saddr);
 		}
 	}
 
-- 
2.7.3

>From 57c57fdc9ddbfa627660117d4d257e17dc4c6b3f Mon Sep 17 00:00:00 2001
From: David Lamparter <[email-masked]>
Date: Wed, 20 Jul 2016 11:24:46 +0200
Subject: [PATCH 2/3] net/ipv6: add ipv6_rt_get_saddr()

---
 include/net/addrconf.h  |  3 +++
 net/ipv6/addrconf.c     | 26 +++++++++++++++++++++++---
 net/ipv6/fib6_rules.c   |  4 +---
 net/ipv6/route.c        |  3 +--
 net/ipv6/xfrm6_policy.c |  3 ++-
 5 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 33f2652..95cee9a 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -83,6 +83,9 @@ struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
 int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
 		       const struct in6_addr *daddr, unsigned int srcprefs,
 		       struct in6_addr *saddr);
+int ipv6_rt_get_saddr(struct net *net, const struct rt6_info *rt,
+		      const struct in6_addr *daddr, unsigned int srcprefs,
+		      struct in6_addr *saddr);
 int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
 		      u32 banned_flags);
 int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f148278..b0aedd3 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1287,6 +1287,7 @@ struct ipv6_saddr_dst {
 	int scope;
 	int label;
 	unsigned int prefs;
+	const struct in6_addr *nh;
 };
 
 static inline int ipv6_saddr_preferred(int type)
@@ -1518,9 +1519,11 @@ out:
 	return hiscore_idx;
 }
 
-int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
-		       const struct in6_addr *daddr, unsigned int prefs,
-		       struct in6_addr *saddr)
+static int __ipv6_rtdev_get_saddr(struct net *net, const struct rt6_info *rt,
+				  const struct net_device *dst_dev,
+				  const struct in6_addr *daddr,
+				  unsigned int prefs,
+				  struct in6_addr *saddr)
 {
 	struct ipv6_saddr_score scores[2], *hiscore;
 	struct ipv6_saddr_dst dst;
@@ -1537,6 +1540,7 @@ int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
 	dst.scope = __ipv6_addr_src_scope(dst_type);
 	dst.label = ipv6_addr_label(net, daddr, dst_type, dst.ifindex);
 	dst.prefs = prefs;
+	dst.nh = rt ? &rt->rt6i_gateway : NULL;
 
 	scores[hiscore_idx].rule = -1;
 	scores[hiscore_idx].ifa = NULL;
@@ -1599,8 +1603,24 @@ int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
 	in6_ifa_put(hiscore->ifa);
 	return 0;
 }
+
+int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
+		       const struct in6_addr *daddr, unsigned int prefs,
+		       struct in6_addr *saddr)
+{
+	return __ipv6_rtdev_get_saddr(net, NULL, dst_dev, daddr, prefs, saddr);
+}
 EXPORT_SYMBOL(ipv6_dev_get_saddr);
 
+int ipv6_rt_get_saddr(struct net *net, const struct rt6_info *rt,
+		      const struct in6_addr *daddr, unsigned int prefs,
+		      struct in6_addr *saddr)
+{
+	const struct net_device *dst_dev = ip6_dst_idev(&rt->dst)->dev;
+	return __ipv6_rtdev_get_saddr(net, rt, dst_dev, daddr, prefs, saddr);
+}
+EXPORT_SYMBOL(ipv6_rt_get_saddr);
+
 int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
 		      u32 banned_flags)
 {
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index ed33abf..d91b6f5 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -104,9 +104,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
 		    r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) {
 			struct in6_addr saddr;
 
-			if (ipv6_dev_get_saddr(net,
-					       ip6_dst_idev(&rt->dst)->dev,
-					       &flp6->daddr,
+			if (ipv6_rt_get_saddr(net, rt, &flp6->daddr,
 					       rt6_flags2srcprefs(flags),
 					       &saddr))
 				goto again;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index ed44663..8e6218d 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2546,8 +2546,7 @@ int ip6_route_get_saddr(struct net *net,
 	if (rt && rt->rt6i_prefsrc.plen)
 		*saddr = rt->rt6i_prefsrc.addr;
 	else
-		err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
-					 daddr, prefs, saddr);
+		err = ipv6_rt_get_saddr(net, rt, daddr, prefs, saddr);
 	return err;
 }
 
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index c074771..19005e6 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -64,7 +64,8 @@ static int xfrm6_get_saddr(struct net *net, int oif,
 		return -EHOSTUNREACH;
 
 	dev = ip6_dst_idev(dst)->dev;
-	ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6);
+	ipv6_rt_get_saddr(dev_net(dev), (struct rt6_info *)dst,
+			  &daddr->in6, 0, &saddr->in6);
 	dst_release(dst);
 	return 0;
 }
-- 
2.7.3

>From f396b90dc6dfd36f282ba574c1add619d7345ad3 Mon Sep 17 00:00:00 2001
From: David Lamparter <[email-masked]>
Date: Wed, 20 Jul 2016 11:25:23 +0200
Subject: [PATCH 3/3] net/ipv6: implement RFC6724 (addrconf) rule 5.5

---
 net/ipv6/addrconf.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index b0aedd3..64ea39d 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1262,6 +1262,7 @@ enum {
 	IPV6_SADDR_RULE_HOA,
 #endif
 	IPV6_SADDR_RULE_OIF,
+	IPV6_SADDR_RULE_OIF_RTR,
 	IPV6_SADDR_RULE_LABEL,
 	IPV6_SADDR_RULE_PRIVACY,
 	IPV6_SADDR_RULE_ORCHID,
@@ -1312,6 +1313,7 @@ static int ipv6_get_saddr_eval(struct net *net,
 			       int i)
 {
 	int ret;
+	size_t j;
 
 	if (i <= score->rule) {
 		switch (i) {
@@ -1390,6 +1392,18 @@ static int ipv6_get_saddr_eval(struct net *net,
 		ret = (!dst->ifindex ||
 		       dst->ifindex == score->ifa->idev->dev->ifindex);
 		break;
+	case IPV6_SADDR_RULE_OIF_RTR:
+		/* Rule 5.5: Prefer prefixes announced by nexthop */
+		ret = 0;
+		if (!dst->nh)
+			break;
+		for (j = 0; j < score->ifa->origin_rtr_count; j++)
+			if (ipv6_addr_equal(&score->ifa->origin_rtr[j],
+					    dst->nh)) {
+				ret = 1;
+				break;
+			}
+		break;
 	case IPV6_SADDR_RULE_LABEL:
 		/* Rule 6: Prefer matching label */
 		ret = ipv6_addr_label(net,
-- 
2.7.3

---

From: Brian E Carpenter <[email-masked]>
Date: Thu, 21 Jul 2016 00:59:05 +1200

> useful and IMHO should be explored.

And please note that draft-ietf-6man-multi-homed-host-07 (in IETF Last Call)
recommends hosts to support this, exactly to assist SADR solutions.

    Brian

---

From: David Lamparter <[email-masked]>
Date: Wed, 20 Jul 2016 15:06:36 +0200

> recommends hosts to support this, exactly to assist SADR solutions.

Yay!  I'm also happy to add that googling around the topic tells me at
least Windows already implements rule 5.5:
http://blog.ipspace.net/2016/01/ipv6-address-allocation-is-operating.html

-David

---

From: Lorenzo Colitti <[email-masked]>
Date: Wed, 20 Jul 2016 15:13:05 +0200

>   possibly have a copy of the PA's valid time?

The way I thought of doing this would be to alternatively/additionally keep
a pointer from the default router that announced a given prefix (which does
have the link-local address of the router) to each address that was
configured from that prefix. That way, when an address goes away you can
scan the FIB and find another router to associate with that prefix.

As for lifetimes expiring, you would need to have somewhere to keep dummy
zero-lifetime default routes. It might be possible to do this in the FIB
itself by adding a special entry that doesn't ever match anything, or has
an infinite metric, or a different type...

---

From: Brian E Carpenter <[email-masked]>
Date: Thu, 21 Jul 2016 01:22:15 +1200

> an infinite metric, or a different type...

Please tell us ASAP if there is anything we should add to
https://tools.ietf.org/html/draft-ietf-6man-multi-homed-host-03#section-3.2
or thereabouts.

    Brian

---

From: David Lamparter <[email-masked]>
Date: Wed, 20 Jul 2016 15:38:07 +0200

On Wed, Jul 20, 2016 at 03:13:05PM +0200, Lorenzo Colitti wrote:
> configured from that prefix.

That turns nontrivial as soon as you have 4191 RIOs, especially if the
router is trying to do walled gardens by sending its RAs with lifetime =
0 (as suggested in section 4.2.2 of pa-multihoming).

> That way, when an address goes away you can scan the FIB and find
> another router to associate with that prefix.

[I assume "address goes away" meant "router goes away"]

> an infinite metric, or a different type...

That sounds quite a bit more complicated than address-centric
handling...  we're 1:N for router['s LL address] to routes and also 1:N
for router['s LL address] to prefixes, and then 1:N for prefix to
derived addresses.

I'd rather copy the prefix lifetime (either valid or preferred -
probably former?) onto the same list entry where a configured address's
RA source LL is also stored; that replicates only the last 1:N step...
(So, for each address, in its list of RA sources that the prefix was
seen from, there will be a potentially-distinct lifetime.)

-David

P.S.: Does anyone know the details of how Windows implements this?

---

From: David Lamparter <[email-masked]>
Date: Wed, 20 Jul 2016 16:34:10 +0200

> https://tools.ietf.org/html/draft-ietf-6man-multi-homed-host-03#section-3.2

I do see some trouble in use-cases where more than one actual router
(actual = not counting extra link-local addresses on the same router) is
present on a link, advertising the same prefix to hosts.  (This is
reasonably likely in homenet scenarios, maybe less in enterprise.)

If the host only tracks a maximum of one RA source LL for a
prefix/address, but the router with that LL happens to not be the one
actually used (e.g. preference, router gone, more specific route from
RIO, whatever else) then the functionality is lost.  It's particularly
bad if the one RA source LL is the one prefix was first seen from (and
then, worst-case, never updated).

(The neccessary precondition / assumption being broken there is that the
test "was prefix X announced by router Y" doesn't report false
negatives.  I haven't applied brain to false positives yet.)

-David

---

From: Brian E Carpenter <[email-masked]>
Date: Thu, 21 Jul 2016 19:25:45 +1200

> negatives.  I haven't applied brain to false positives yet.)

Is this any worse than if the single default router in a traditional host
goes away, which will break all off-link packets until something happens?

I'm not saying it isn't a problem, but it doesn't sound like it's a new
problem that applies only in the multihomed case.

    Brian

---

From: Lorenzo Colitti <[email-masked]>
Date: Thu, 21 Jul 2016 09:49:46 +0200

> to this mail.  I've been able to gleam a little more detail on the idea:

David, do you intend to keep working on the patches? Think you could send
them to netdev as an RFC patchset, with proper signoff? Once it's on netdev
other people can iterate on them, even if you lose interest :-)

---

From: David Lamparter <[email-masked]>
Date: Thu, 21 Jul 2016 12:21:53 +0200

> goes away, which will break all off-link packets until something happens?

Yes -- this breaks the application of 6724 5.5 for the specific goal of
preferring the correct source address for a particular uplink, if there
is more than one router advertising the same prefix and the host can
only remember one router.  I.e., a scenario like this:

#        +--- R1 ------- ISP_A
#        |
# Host --+--- R2 ---+
#        |          +--- ISP_B
#        +--- R3 ---+

Where R1 advertises Prefix A (ISP A) and R2 and R3 advertise Prefix B
(ISP B).
If R2 goes away and the Host only associated Prefix B with R2 (because
it only saves a single LL address), then it can end up using R3 but with
source prefix A.  Meanwhile there is enough information floating on the
link for it to know that it shouldn't.

I'm not completely convinced this needs to be in the draft explicitly;
if so this is a sentence or two along the lines of "a host SHOULD
remember all/multiple routers that have advertised a particular prefix",
or maybe "for full capability, the host needs to be capable of correctly
tracking N:M prefix to router relations", or something similar.

The question is whether that needs to be spelled out or not.  I don't
have a strong opinion.  Windows managed to implement it without RFC
guidance -- can anyone find out if it tracks N:M?

-David

---

From: David Lamparter <[email-masked]>
Date: Wed, 27 Jul 2016 20:39:10 +0200

> other people can iterate on them, even if you lose interest :-)

I've uploaded the patches (with signoffs) to:
https://aurora.nox.tf/tmp/rule55/

NB: patch 2 of 3 is slightly different from the version I mailed, I
accidentally lost a NULL check in ipv6_rt_get_saddr().

I do _not_ intend to continue working on these since I now believe the
functionality should be put on neighbor cache entries.  This requires
some (minor IMHO) rework to make these neighbor entries stay alive until
their prefix information times out.  By putting it there, it can support
addresses that are configured from dhcpv6 or static/admin.  The code
linked above only works for SLAAC.

=> the patches are intended purely for testing, for example if someone
hacks on the router side and wants to use Linux VMs to test the full
picture.

Cheers,

-David

---

From: David Lamparter <[email-masked]>
Date: Wed, 27 Jul 2016 21:49:23 +0200

> >> https://tools.ietf.org/html/draft-ietf-6man-multi-homed-host-03#section-3.2

I believe we need to ship the following text (or something similar)
/somewhere/:

(Some points - particularly 7, 8 & 10 - might need some arguing about.
Text below is what I /believe/ to be reasonable, but I may of course
have overlooked some scenarios...)

Cheers / hoping for feedback,

-David

P.S.: Praveen - this is what I was wondering about when I asked you @
Bits'n'Bytes in Berlin.  Can you provide some insight into how Windows
implements this?

---
section: Rule 5.5 implementation considerations

Since neither RFC 4861 nor RFC 4191 detailed notes on how to "remember
which next-hops advertised which prefixes" [RFC 6724], these are listed
here:

1. Note RFC 6724 mentions "SA or SA's prefix".  This is redundant for
   SLAAC-derived addresses but needs to be considered for DHCPv6 and
   admin-configured addresses.  If a router advertises a particular
   prefix, addresses in that prefix SHOULD be preferred regardless of
   the mechanism used to configure them.

2. Neither L nor A bit in the Prefix Information Option (PIO) are
   specified anywhere to have an impact on source address selection.
   Hosts SHOULD consider all PIOs regardless of L/A bit values for the
   purposes of source address selection.

3. When using non-default routes learned from Route Information Options,
   hosts SHOULD apply the rules in the same manner, preferring source
   addresses inside prefixes advertised by the nexthop of the specific
   route used.

4. Routers MAY advertise more than one prefix (e.g. during renumbering),
   which hosts SHOULD honor up to a limit imposed by security
   considerations.

5. More than one router MAY advertise the same prefix.  In particular,
   homenet routers implementing RFCs 7695 and 7788 will exhibit this
   behaviour by default and in normal operation.  Hosts SHOULD be able
   to correctly retain identical prefixes for multiple routers, up to a
   limit imposed by security considerations.

6. A router MAY choose to include prefix information only in some of its
   RAs, for example when the sum of RA options exceeds the link's MTU.
   A host MUST NOT rely on all RAs including all information.  This also
   means a host MUST NOT implement rule 5.5 by keeping a copy of the
   last RA packet, as that packet may not have all information.

7. Entries on a router's list of advertised prefixes need to be expired
   using the prefix's (TBD: valid or preferred?) lifetime.  Hosts SHOULD
   apply the same rules regarding lifetimes as if they were configuring
   an address from that prefix.

8. A host MAY dismiss a router's list of advertised prefixes if all
   routes via that router expire.  If a host does so, it MUST ensure
   that additional routes learned from Route Information Options cause
   it to retain the list even if the default route expires (i.e. had a
   lower lifetime), or is not added to begin with.

9. Hosts MUST NOT use link-layer addresses to identify routers.  Not
   only is this information unreliable on some media (e.g. 802.11 with
   aggressive controller-based optimizations), but it also conflicts
   with (future) approaches to exploit rule 5.5 for multihoming
   scenarios.  Hosts MUST use IPv6 link-local addresses to identify
   routers for this purpose.

10. Hosts SHOULD retain prefix information even if they have no address
    inside that prefix.  Not doing so delays the application of improved
    source address selection for DHCPv6 and admin-configured addresses
    until the next receipt of a RA packet.  This can be visible to the
    user as a temporary period of failed service, or, if RAs are
    infrequent, be interpreted as entirely broken connectivity.

section: Security Considerations

Retaining additional information from router advertisements opens hosts
to another avenue of memory exhaustion attacks by malicious on-link
hosts.  Implementations MUST cap the amount of data retained.

section: Privacy Considerations

If hosts incorrectly mix prefix information across multiple interfaces,
it becomes possible for malicious on-link hosts (or routers) to
enumerate all of a host's IPv6 addresses.  Hosts therefore MUST keep
this information strictly scoped to the respective interface.

Routers generally gain a method of insight into a host's addresses.
This extends existing considerations applying to rogue RAs.  The problem
is particularly relevant on link layers where the broadcast domain is
shattered into non-transitive subdomains (e.g. Private VLANs [RFC
5517]).  Even if RAs are secured in some way, privacy is not provided
between multiple routers on the same link.

section: Acknowledgements

This text/section/... was added by David Lamparter based on
implementation observations and discussions with Lorenzo Colitti and Jen
Linkova.

---

From: Brian E Carpenter <[email-masked]>
Date: Thu, 28 Jul 2016 08:19:04 +1200

David,

> I believe we need to ship the following text (or something similar)

I like what you wrote. I don't think such eminently practical information
fits very well into IETF documents but I'd be interested in other opionions.
draft-ietf-6man-multi-homed-host is in IETF LC and already on the IESG agenda,
so if we should add this sort of material Suresh had better tell us to
do so rather soon. One specific comment below...

>    purposes of source address selection.

Yes, including L=0 and A=0, as explicitly called out at the end of
https://tools.ietf.org/html/draft-ietf-6man-multi-homed-host-07#section-2.1

   Brian

---

From: Hemant Singh <[email-masked]>
Date: Wed, 27 Jul 2016 20:47:29 -0400

First, if the doc is in the IESG, so much text does not make sense to add
to the doc at this juncture.
Second, I agree with Brian that it is mostly practical information that
does not belong in an IETF RFC.
Third, it is too much text and the text has to be thoroughly reviewed by a
wide audience.  I reviewed the proposed text and see most items are not
necessary.

I have my review comments in line below preceded by "<hs>".

> which next-hops advertised which prefixes" [RFC 6724], these are listed

<hs> It is deliberate.  If a host tracks prefixes advertised by a specific
router, RFC 4861 and RFC 4191 require a change which needs to be discussed.

>    SLAAC-derived addresses

<hs> Not quite.  Also, a renumbering takes place and Prefix A is advertised
with reduced lifetime which eventually goes to zero.  Now each destination
that matches Prefix A is off-link.   Router A advertised SA Prefix A and
router B advertised SA Prefix B.  Now router selection is needed at the
host.  What SLAAC address is used for SA requires more work that a
redundant "on-link" for any SLAAC prefix.

but needs to be considered for DHCPv6 and
>    the mechanism used to configure them.

<hs>RFC4861 already covers a union of information from RA and DHCPv6 for
use by the host.  See section 6.3.4 in RFC4861 and this text: "Hosts accept
the union of all received information;"

>    purposes of source address selection.

<hs> No. If the lifetime in the PIO is zero, more work is needed to pick a
source address.

>    addresses inside prefixes advertised by the nexthop of the specific

<hs>Minor comment first.  IPv6 ND has no concept of a default route.  ND
specifies a default router for the link.   The text in this item 3 is not
needed.  When a packet is to be sent out, the host performs a longest
prefix match of the packet destination with prefixes in the Prefix List.
If a match is found, the next-hop is the packet destination.  If not, the
packet is forwarded to the default router.   If the host supports RFC 4191,
the rules are already specified in RFC 4191 for routing table.

>    which hosts SHOULD honor up to a limit imposed by security

<hs> Already covered in RFC 4861 and RFC 4862.  See section 5.5.4 in RFC
4862 and sections 6.3.5 and 12 in RFC 4861.

> <hs> Could you please provide specific text and sections from the homenet
RFCs to show why multiple routers advertise the same prefix and what is the
reason for doing so.  A topology diagram would help - maybe the diagram
exists in a homenet doc.   Then we can discuss.

>    last RA packet, as that packet may not have all information.

<hs> Section 6.3.4 of RFC 4861 already covers such details and thus Rule
5.5 of RFC 6724 is fine.

>    an address from that prefix.

<hs> It is the Preferred Lifetime.  RFC 4862 already includes the behavior
you describe above for SLAAC addresses.  DHCPv6 has address renew
mechanisms to refresh address before the address expires.   I don't see a
need to text in item 7 above.

>    lower lifetime), or is not added to begin with.

<hs> Text is not needed.  Section 6.3.5 clears specifies how to timeout
entries in the Prefix List and the Default Router List.

> <hs> If the RA includes a Source Link-layer address via the Source
Link-layer address Option (SLAO), the host is legal to use the link-layer
address.  If a link does not use Source Link-layer address, then no SLAO is
included in the RA.   How is a packet forwarded by the host to the default
router if the host does not know the link-layer address of the default
router?    More details on 802.11 optimizations are needed before the text
in item 9 is considered.

> <hs> A better model exists if the hosts only use DHCPv6.  The router sends
an RA with no PIO with the M and O bits set,  Thus hosts have all
non-link-local destinations as off-link.

> <hs> RFC 4861, in section 5.3 already says "However, a node may garbage-collect
entries prematurely if it is low on memory."

> this information strictly scoped to the respective interface.

<hs> IPv6 ND and SLAAC are protocols that work for a specific interface.
Thus this information is blatantly clear.  If host mix information, it's a
bug in the host implementation to fix.  No new text to IETF RFCs is needed.

> <hs>Again, the RA is promiscuous for a specific private VLAN domain.  It
> is clear and obvious information.
>

Hemant

---

From: Hemant Singh <[email-masked]>
Date: Thu, 28 Jul 2016 08:25:27 -0400

Brian/Fred,

Does it make sense to add a new section towards the end of the draft
below.  The new section is titled "Changes to RFC 4861" and lists specific
changes in the new section.

Thanks,

Hemant

On Wed, Jul 27, 2016 at 4:19 PM, Brian E Carpenter <
[email-masked]> wrote:

> David,
>
>
> https://tools.ietf.org/html/draft-ietf-6man-multi-homed-host-03
> <https://tools.ietf.org/html/draft-ietf-6man-multi-homed-host-03#section-3.2>
>
>

---

From: Brian E Carpenter <[email-masked]>
Date: Fri, 29 Jul 2016 11:24:20 +1200

Hemant,

> changes in the new section.

We do say this in the Introduction:
"Nevertheless, implementers of Sections 5.2, 6.2.3, 6.3.4 and 8 of RFC
4861 will need to extend their implementations accordingly."
Is that specific enough? I think it's very hard to say more without
making assumptions about individual implementations.

(Reminder: the IETF Last Call on draft-ietf-6man-multi-homed-host expires 2016-08-04.)

Regards
    Brian

---

From: Hemant Singh <[email-masked]>
Date: Thu, 28 Jul 2016 19:31:52 -0400

Brian,

Ok, works for me - we can skip adding the new section.  Thanks to you and
Fred for working on this doc.

Hemant

---

From: Suresh Krishnan <[email-masked]>
Date: Fri, 29 Jul 2016 03:30:18 +0000

Hi Brian,

> do so rather soon. One specific comment below...

I agree with your assessment that this is closely tied to implementation 
details and does not belong here, but I am also fine if you would like to add 
some form of generic explanatory text in this regard. Feel free to discuss 
text proposals until the IETF Last Call completes. If there are no other Last 
Call comments we can handle this text addition along with any that are 
necessitated by IESG evaluation.

Thanks
Suresh