Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gnrc_netif: highest source address scope wins selection #12409

Merged

Conversation

miri64
Copy link
Member

@miri64 miri64 commented Oct 9, 2019

Contribution description

Rule 2 of the source address algorithm outlined in RFC6724 states the possible source addresses must also be compared among each other:

Rule 2: Prefer appropriate scope.
If Scope(SA) < Scope(SB): If Scope(SA) < Scope(D), then prefer SB and
otherwise prefer SA.  Similarly, if Scope(SB) < Scope(SA): If
Scope(SB) < Scope(D), then prefer SA and otherwise prefer SB.

Our current implementation doesn't do that. It just checks if the scope of a possible source is lesser than the scope of the destination (which involves the second "If" in the rule).

This fix grants points according to the scope of an address. If the scope matches, they get the highest points, ensuring that the selected source will always be reachable from the destination.

Testing procedure

Pinging between different and same scopes should still work (or even work for the first time).

Issues/PRs references

Follow-up to #12404 and #12408.

@miri64 miri64 added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Area: network Area: Networking labels Oct 9, 2019
@miri64 miri64 added this to the Release 2020.01 milestone Oct 9, 2019
@miri64 miri64 requested review from OlegHahm and kaspar030 October 9, 2019 16:47
@tcschmidt
Copy link
Member

@cgundogan can you test against the RFC spec?

@miri64
Copy link
Member Author

miri64 commented Oct 12, 2019

@cgundogan @tcschmidt please be aware that without #12408 the result of the source address selection gets skewed to the first address assigned to the interface [edit]that won the rest of source address selection[/edit] in any case, so the scope contention might not even come through.

@miri64 miri64 requested a review from a team October 21, 2019 14:11
@fjmolinas
Copy link
Contributor

@miri64 this one needs rebasing now.

@miri64 miri64 force-pushed the gnrc_netif/fix/highest-source-scope-wins branch from e95fc80 to 147e161 Compare October 24, 2019 15:25
@miri64
Copy link
Member Author

miri64 commented Oct 24, 2019

Rebased to current master. Please make sure to test this also wrt site-local addresses.

@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Nov 4, 2019
@benpicco
Copy link
Contributor

How would the testing procedure look like / how did you test this?

@miri64
Copy link
Member Author

miri64 commented Nov 19, 2019

How would the testing procedure look like / how did you test this?

I tested it like I described in the testing procedure, I think (sorry I don't remember exactly). I think for a more in-depth test, one needs to find a set of addresses, where all the other rules result in equal ranking but not the scope and use one of them as destination address and the rest is assigned to the interface as potential source addresses. The largest scope then should win. There can only be three scopes: global, site-local and link-local from largest to smallest.

@fjmolinas fjmolinas self-requested a review January 3, 2020 19:47
Copy link
Contributor

@fjmolinas fjmolinas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@miri64 the code changes look good and make sense with the RFC, that being said I'm having trouble to understand how I should test this, I understand the test cases but to be completely honest I dont understand how to test scopes regarding multicast address. Should I just add them to the group and ping that group?

@@ -1067,11 +1064,11 @@ static ipv6_addr_t *_src_addr_selection(gnrc_netif_t *netif,
uint8_t candidate_scope = _get_scope(ptr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't seem to comment on that line but one line above (old 1066, new 1063) has a comment which I do not understand, why does it assume both link=local?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤷‍♀️ It doesn't even do that in the first place. There is just this comment saying "both link local", but it does not say what "both" is referring to and if this is an assumption or something else. This comment goes back to the original implementation of this function and even there it doesn't to anything with link local etc. It is not in the code I touched so I deem it unrelated, but if you want, I can add a piggy-back commit to remove it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not in the code I touched so I deem it unrelated, but if you want, I can add a piggy-back commit to remove it.

Yes it is unrelated but since if was under rule 2, It got me confused. You can add the commit or not, as you said it is unrelated.

@miri64
Copy link
Member Author

miri64 commented Jan 10, 2020

that being said I'm having trouble to understand how I should test this, I understand the test cases but to be completely honest I dont understand how to test scopes regarding multicast address. Should I just add them to the group and ping that group?

There is no involvement of multicast here (unless of course you want to use it as a destination address, but you don't have to). The scope values from multicast addresses are just used because they happen to provide a standadized numerical order to scopes (I believe; just re-using what was there from @OlegHahm's implementation).

@fjmolinas
Copy link
Contributor

There is no involvement of multicast here (unless of course you want to use it as a destination address, but you don't have to). The scope values from multicast addresses are just used because they happen to provide a standadized numerical order to scopes (I believe; just re-using what was there from @OlegHahm's implementation).

If there is no involvement of multicast how can the scopes be different? From what I understand unicast can have either gobal or local scope. So there would be no case for two candidates to have smaller scope but not equal right? either they both have smaller and equal or one have the same scope.

@fjmolinas
Copy link
Contributor

Ok so I have two nodes with link-local and global scope:

node1 ifconfig
Iface  6  HWaddr: 11:15  Channel: 26  Page: 0  NID: 0x23
          Long HWaddr: 06:BC:FB:65:10:6B:11:15 
           TX-Power: 0dBm  State: IDLE  max. Retrans.: 3  CSMA Retries: 4 
          AUTOACK  ACK_REQ  CSMA  L2-PDU:102 MTU:1280  HL:64  RTR  
          RTR_ADV  6LO  IPHC  
          Source address length: 8
          Link type: wireless
          inet6 addr: fe80::4bc:fb65:106b:1115  scope: link  VAL
          inet6 addr: 2001:6d6f:6c69:6e61:4bc:fb65:106b:1115  scope: global  VAL
          inet6 group: ff02::2
          inet6 group: ff02::1
          inet6 group: ff02::1:ff6b:1115
          

node2 ifconfig
Iface  7  HWaddr: 0F:36  Channel: 26  Page: 0  NID: 0x23
          Long HWaddr: 15:11:6B:10:65:FA:8F:36 
           TX-Power: 0dBm  State: IDLE  max. Retrans.: 3  CSMA Retries: 4 
          AUTOACK  ACK_REQ  CSMA  L2-PDU:102 MTU:1280  HL:64  RTR  
          RTR_ADV  6LO  IPHC  
          Source address length: 8
          Link type: wireless
          inet6 addr: fe80::1711:6b10:65fa:8f36  scope: link  VAL
          inet6 addr: 2001:6d6f:6c69:6e61:1711:6b10:65fa:8f36  scope: global  VAL
          inet6 group: ff02::2
          inet6 group: ff02::1
          inet6 group: ff02::1:fffa:8f36
          inet6 group: ff02::1a

ping6 2001:6d6f:6c69:6e61:4bc:fb65:106b:1115 
2020-01-10 17:48:46,100 #  ping6 2001:6d6f:6c69:6e61:4bc:fb65:106b:1115
2020-01-10 17:48:46,102 # finding the best match within the source address candidates
2020-01-10 17:48:46,104 # Checking address: fe80::1711:6b10:65fa:8f36
2020-01-10 17:48:46,105 # winner for rule 2 (smaller scope) found
2020-01-10 17:48:46,107 # winner for rule 3 found
2020-01-10 17:48:46,108 # Checking address: 2001:6d6f:6c69:6e61:1711:6b10:65fa:8f36
2020-01-10 17:48:46,109 # winner for rule 2 (same scope) found
2020-01-10 17:48:46,110 # winner for rule 3 found
2020-01-10 17:48:46,111 # Winner is: 2001:6d6f:6c69:6e61:1711:6b10:65fa:8f36

ping6 fe80::4bc:fb65:106b:1115 
2020-01-10 17:49:18,194 # ping6 fe80::4bc:fb65:106b:1115
2020-01-10 17:49:18,197 # finding the best match within the source address candidates
2020-01-10 17:49:18,199 # Checking address: fe80::1711:6b10:65fa:8f36
2020-01-10 17:49:18,200 # winner for rule 2 (same scope) found
2020-01-10 17:49:18,201 # winner for rule 3 found
2020-01-10 17:49:18,203 # Checking address: 2001:6d6f:6c69:6e61:1711:6b10:65fa:8f36
2020-01-10 17:49:18,204 # winner for rule 3 found
2020-01-10 17:49:18,206 # Winner is: fe80::1711:6b10:65fa:8f36
2020-01-10 17:49:18,211 # 12 bytes from fe80::4bc:fb65:106b:1115: icmp_seq=0 ttl=64 rssi=-58 dBm time=13.421 ms

That works correctly.

@miri64
Copy link
Member Author

miri64 commented Jan 10, 2020

If there is no involvement of multicast how can the scopes be different? From what I understand unicast can have either gobal or local scope. So there would be no case for two candidates to have smaller scope but not equal right? either they both have smaller and equal or one have the same scope.

There are the deprecated site-local address, which would provide another level of scope.

@miri64
Copy link
Member Author

miri64 commented Jan 10, 2020

There are still problems with wide-scoped multicast addresses so I would not use them for testing. See #4527 and #5230.

@fjmolinas
Copy link
Contributor

In RFC 4291: Site-Local IPv6 Unicast Addresses

The special behavior of this prefix defined in [RFC3513] must no
   longer be supported in new implementations (i.e., new implementations
   must treat this prefix as Global Unicast).

So I guess alltough good, it doesn't need to be supported?

@miri64
Copy link
Member Author

miri64 commented Jan 10, 2020

For multicast AFAIK site local is not deprecated and it is the same check (in a function I don't touch in this PR), so no sense in removing it here.

@fjmolinas
Copy link
Contributor

fjmolinas commented Jan 10, 2020

Thanks @miri64, sorry for asking so many questions. I'm got got quite confused between the RFC's. I changed my setup, two nodes with these address:

node1:

2020-01-10 18:20:21,972 #           inet6 addr: fe80::7b65:3458:ecde:6b82  scope: link  VAL
2020-01-10 18:20:21,978 #           inet6 addr: fd01::7b65:3458:ecde:6b82  scope: global  VAL

node2:

2020-01-10 18:19:11,656 #           inet6 addr: fd01::1711:6b10:65fa:8f36  scope: global  VAL
2020-01-10 18:19:11,658 #           inet6 addr: fec0::1711:6b10:65fa:8f36  scope: site  VAL

From node2 to node1 link local, site local wins.

ping6 fe80::7b65:3458:ecde:6b82
2020-01-10 18:21:42,352 # ping6 fe80::7b65:3458:ecde:6b82
2020-01-10 18:21:42,354 # finding the best match within the source address candidates
2020-01-10 18:21:42,356 # Checking address: fd01::1711:6b10:65fa:8f36
2020-01-10 18:21:42,357 # winner for rule 3 found
2020-01-10 18:21:42,359 # Checking address: fec0::1711:6b10:65fa:8f36
2020-01-10 18:21:42,360 # winner for rule 3 found
2020-01-10 18:21:42,362 # Winner is: fec0::1711:6b10:65fa:8f36
2020-01-10 18:21:43,360 # finding the best match within the source address candidates
2020-01-10 18:21:43,362 # Checking address: fd01::1711:6b10:65fa:8f36
2020-01-10 18:21:43,363 # winner for rule 3 found
2020-01-10 18:21:43,364 # Checking address: fec0::1711:6b10:65fa:8f36
2020-01-10 18:21:43,365 # winner for rule 3 found
2020-01-10 18:21:43,366 # Winner is: fec0::1711:6b10:65fa:8f36
2020-01-10 18:21:44,353 # finding the best match within the source address candidates
2020-01-10 18:21:44,355 # Checking address: fd01::1711:6b10:65fa:8f36
2020-01-10 18:21:44,356 # winner for rule 3 found
2020-01-10 18:21:44,358 # Checking address: fec0::1711:6b10:65fa:8f36
2020-01-10 18:21:44,359 # winner for rule 3 found
2020-01-10 18:21:44,360 # Winner is: fec0::1711:6b10:65fa:8f36

From node2 to node1 global, global wins.

> ping6 fd01::7b65:3458:ecde:6b82 
2020-01-10 18:22:17,726 #  ping6 fd01::7b65:3458:ecde:6b82
2020-01-10 18:22:17,728 # finding the best match within the source address candidates
2020-01-10 18:22:17,730 # Checking address: fd01::1711:6b10:65fa:8f36
2020-01-10 18:22:17,732 # winner for rule 2 (same scope) found
2020-01-10 18:22:17,732 # winner for rule 3 found
2020-01-10 18:22:17,741 # Checking address: fec0::1711:6b10:65fa:8f36
2020-01-10 18:22:17,743 # winner for rule 2 (smaller scope) found
2020-01-10 18:22:17,744 # winner for rule 3 found
2020-01-10 18:22:17,745 # Winner is: fd01::1711:6b10:65fa:8f36
2020-01-10 18:22:18,734 # finding the best match within the source address candidates
2020-01-10 18:22:18,736 # Checking address: fd01::1711:6b10:65fa:8f36
2020-01-10 18:22:18,738 # winner for rule 2 (same scope) found
2020-01-10 18:22:18,739 # winner for rule 3 found
2020-01-10 18:22:18,741 # Checking address: fec0::1711:6b10:65fa:8f36
2020-01-10 18:22:18,742 # winner for rule 2 (smaller scope) found
2020-01-10 18:22:18,743 # winner for rule 3 found
2020-01-10 18:22:18,745 # Winner is: fd01::1711:6b10:65fa:8f36
2020-01-10 18:22:19,727 # finding the best match within the source address candidates
2020-01-10 18:22:19,728 # Checking address: fd01::1711:6b10:65fa:8f36
2020-01-10 18:22:19,730 # winner for rule 2 (same scope) found
2020-01-10 18:22:19,731 # winner for rule 3 found
2020-01-10 18:22:19,741 # Checking address: fec0::1711:6b10:65fa:8f36
2020-01-10 18:22:19,743 # winner for rule 2 (smaller scope) found
2020-01-10 18:22:19,744 # winner for rule 3 found
2020-01-10 18:22:19,745 # Winner is: fd01::1711:6b10:65fa:8f36

@fjmolinas
Copy link
Contributor

fjmolinas commented Jan 10, 2020

@miri64 can you confirm that mightmy output makes sense :D ? Nope missing case.

Copy link
Contributor

@fjmolinas fjmolinas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is working, but I think not correctly since in my second test both sources should win Rule 2. See my suggested changes. EDIT this is not working in case 1 they should have the same preference and in case two proper address is selected by chance but Rule 2 is not evaluated. (Unless i'm understanding scopes completely the other way around)

  • Scope(SA) < Scope(SB) < Scope(D) : prefered fec0::1711:6b10:65fa:8f36
2020-01-10 18:32:46,347 #           inet6 addr: fe80::1711:6b10:65fa:8f36  scope: link  VAL
2020-01-10 18:32:46,348 #           inet6 addr: fec0::1711:6b10:65fa:8f36  scope: site  VAL
> ping6 fd00::7b65:3458:ecde:6b82
2020-01-10 18:32:59,171 #  ping6 fd00::7b65:3458:ecde:6b82
2020-01-10 18:32:59,174 # finding the best match within the source address candidates
2020-01-10 18:32:59,175 # Checking address: fe80::1711:6b10:65fa:8f36
2020-01-10 18:32:59,177 # winner for rule 2 (smaller scope) found
2020-01-10 18:32:59,178 # winner for rule 3 found
2020-01-10 18:32:59,180 # Checking address: fec0::1711:6b10:65fa:8f36
2020-01-10 18:32:59,181 # winner for rule 2 (smaller scope) found
2020-01-10 18:32:59,182 # winner for rule 3 found
2020-01-10 18:32:59,184 # Winner is: fec0::1711:6b10:65fa:8f36
2020-01-10 18:33:00,164 # finding the best match within the source address candidates
2020-01-10 18:33:00,166 # Checking address: fe80::1711:6b10:65fa:8f36
2020-01-10 18:33:00,178 # winner for rule 2 (smaller scope) found
2020-01-10 18:33:00,179 # winner for rule 3 found
2020-01-10 18:33:00,181 # Checking address: fec0::1711:6b10:65fa:8f36
2020-01-10 18:33:00,183 # winner for rule 2 (smaller scope) found
2020-01-10 18:33:00,184 # winner for rule 3 found
2020-01-10 18:33:00,185 # Winner is: fec0::1711:6b10:65fa:8f36
2020-01-10 18:33:01,172 # finding the best match within the source address candidates
2020-01-10 18:33:01,174 # Checking address: fe80::1711:6b10:65fa:8f36
2020-01-10 18:33:01,175 # winner for rule 2 (smaller scope) found
2020-01-10 18:33:01,176 # winner for rule 3 found
2020-01-10 18:33:01,178 # Checking address: fec0::1711:6b10:65fa:8f36
2020-01-10 18:33:01,180 # winner for rule 2 (smaller scope) found
2020-01-10 18:33:01,180 # winner for rule 3 found
2020-01-10 18:33:01,181 # Winner is: fec0::1711:6b10:65fa:8f36
  • Scope(D) < Scope(SA) < Scope(SB): prefered fec0::7b65:3458:ecde:6b82
2020-01-10 18:40:40,730 #           inet6 addr: fec0::7b65:3458:ecde:6b82  scope: site  VAL
2020-01-10 18:40:40,736 #           inet6 addr: fd00::7b65:3458:ecde:6b82  scope: global  VAL
2020-01-10 18:40:27,323 # ping6 fe80::1711:6b10:65fa:8f36
2020-01-10 18:40:27,329 # finding the best match within the source address candidates
2020-01-10 18:40:27,333 # Checking address: fec0::7b65:3458:ecde:6b82
2020-01-10 18:40:27,335 # winner for rule 3 found
2020-01-10 18:40:27,339 # Checking address: fd00::7b65:3458:ecde:6b82
2020-01-10 18:40:27,341 # winner for rule 3 found
2020-01-10 18:40:27,345 # Winner is: fec0::7b65:3458:ecde:6b82
2020-01-10 18:40:27,363 # 12 bytes from fe80::1711:6b10:65fa:8f36: icmp_seq=0 ttl=64 rssi=-46 dBm time=31.844 ms
2020-01-10 18:40:28,329 # finding the best match within the source address candidates
2020-01-10 18:40:28,333 # Checking address: fec0::7b65:3458:ecde:6b82
2020-01-10 18:40:28,335 # winner for rule 3 found
2020-01-10 18:40:28,339 # Checking address: fd00::7b65:3458:ecde:6b82
2020-01-10 18:40:28,341 # winner for rule 3 found
2020-01-10 18:40:28,345 # Winner is: fec0::7b65:3458:ecde:6b82
2020-01-10 18:40:28,360 # 12 bytes from fe80::1711:6b10:65fa:8f36: icmp_seq=1 ttl=64 rssi=-46 dBm time=28.661 ms
2020-01-10 18:40:29,329 # finding the best match within the source address candidates
2020-01-10 18:40:29,333 # Checking address: fec0::7b65:3458:ecde:6b82
2020-01-10 18:40:29,335 # winner for rule 3 found
2020-01-10 18:40:29,339 # Checking address: fd00::7b65:3458:ecde:6b82
2020-01-10 18:40:29,341 # winner for rule 3 found
2020-01-10 18:40:29,344 # Winner is: fec0::7b65:3458:ecde:6b82

sys/net/gnrc/netif/gnrc_netif.c Outdated Show resolved Hide resolved
sys/net/gnrc/netif/gnrc_netif.c Show resolved Hide resolved
@miri64
Copy link
Member Author

miri64 commented Jan 13, 2020

Addressed comments. I now have a knot in my brain 😅. I also added as a separate commit the proper reading of the scope of multicast addresses.

Copy link
Contributor

@fjmolinas fjmolinas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still some questions...

@@ -892,7 +892,12 @@ static int _match_to_idx(const gnrc_netif_t *netif,

static uint8_t _get_scope(const ipv6_addr_t *addr)
{
if (ipv6_addr_is_link_local(addr)) {
if (ipv6_addr_is_multicast(addr)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also added as a separate commit the proper reading of the scope of multicast addresses.

It's in a fixup, did you mean it like that or you wanted an actual separate commit?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted a fixup. Mainly, because it is a bit beyond the original intention of this PR and I wanted to here your opinion first. I can make it its own commit later-on still.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be a separate commit. I don't mind including it, its needed for multicast but in a different commit.

@@ -1067,7 +1072,16 @@ static ipv6_addr_t *_src_addr_selection(gnrc_netif_t *netif,
}
else if (candidate_scope > dst_scope) {
DEBUG("winner for rule 2 (larger scope) found\n");
winner_set[i] += candidate_scope;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only issue is the case source(SA) < source(SB) < source(D), I find sources that say that in that case they both have the same preference and others that sat SB should be preferred. The RFC makes me think it should be SA, but with the if (candidate_scope > dst_scope) they will both get the same preference.

if (A < B) {
    if( A < D) {
        choose B
    } else {
        choose A
    }
}
else {
    choose A
}

BTW: its been a while since something so simple has given me sucha headache ahahaha, just 2 ifs

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW: its been a while since something so simple has given me sucha headache ahahaha, just 2 ifs

Yeah... but the wording in the RFC could be a little bit more trivial IMHO so no wonder it gives a headache 😅

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I agree with you: the RFC is pretty clear on the case you talked about: It should be SB: if Scope(SA) < Scope(SB) (true in our case) then If Scope(SA) < Scope(D), (also true in our case) pick then prefer SB […].

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(so we need an else case where SB is picked if Scope(SA) < Scope(SB) < Scope(D), but SC, if Scope(SA) < Scope(SB) < Scope(D) < Scope(SC)... I think that makes the scoring a bit more complicated ^^"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fjmolinas I think my latest proposal should make the best selection.

@fjmolinas
Copy link
Contributor

  • Scope(D) < Scope(SA) < Scope(SB): Scope(SA) wins
2020-01-13 17:15:17,285 #           inet6 addr: fd01::1711:6b10:65fb:bc06  scope: global  VAL
2020-01-13 17:15:17,286 #           inet6 addr: fec0::1711:6b10:65fb:bc06  scope: site  VAL
2020-01-13 17:15:35,620 #  ping6 fe80::1711:6b10:65fb:bc06
2020-01-13 17:15:35,621 # finding the best match within the source address candidates
2020-01-13 17:15:35,621 # Checking address: fd01::1711:6b10:65fb:bc06
2020-01-13 17:15:35,622 # winner for rule 2 (larger scope) found
2020-01-13 17:15:35,622 # winner for rule 3 found
2020-01-13 17:15:35,623 # Checking address: fec0::1711:6b10:65fb:bc06
2020-01-13 17:15:35,623 # winner for rule 2 (larger scope) found
2020-01-13 17:15:35,623 # winner for rule 3 found
2020-01-13 17:15:35,623 # Winner is: fec0::1711:6b10:65fb:bc06
  • Scope(SA) < Scope(SB) < Scope(D): Scope(SB) wins
2020-01-13 17:12:41,662 #           inet6 addr: fe80::1711:6b10:65fb:bc06  scope: link  VAL
2020-01-13 17:12:41,662 #           inet6 addr: fec0::1711:6b10:65fb:bc06  scope: site  VAL
2020-01-13 17:14:12,326 # ping6 fd01::7b65:3458:ecde:6b82
2020-01-13 17:14:12,327 # finding the best match within the source address candidates
2020-01-13 17:14:12,327 # Checking address: fe80::1711:6b10:65fb:bc06
2020-01-13 17:14:12,328 # winner for rule 2 (smaller scope) found
2020-01-13 17:14:12,328 # winner for rule 3 found
2020-01-13 17:14:12,329 # Checking address: fec0::1711:6b10:65fb:bc06
2020-01-13 17:14:12,330 # winner for rule 2 (smaller scope) found
2020-01-13 17:14:12,330 # winner for rule 3 found
2020-01-13 17:14:12,331 # Winner is: fec0::1711:6b10:65fb:bc06
  • Scope(SA) < Scope(D) < Scope(SB): Scope(SB) wins
2020-01-13 17:16:27,247 #           inet6 addr: fd01::1711:6b10:65fb:bc06  scope: global  VAL
2020-01-13 17:16:27,247 #           inet6 addr: fe80::1711:6b10:65fb:bc06  scope: link  VAL
2020-01-13 17:16:32,346 # ping6 fec0::1711:6b10:65fb:bc06
2020-01-13 17:16:32,347 # finding the best match within the source address candidates
2020-01-13 17:16:32,347 # Checking address: fd01::1711:6b10:65fb:bc06
2020-01-13 17:16:32,348 # winner for rule 2 (larger scope) found
2020-01-13 17:16:32,348 # winner for rule 3 found
2020-01-13 17:16:32,348 # Checking address: fe80::1711:6b10:65fb:bc06
2020-01-13 17:16:32,349 # winner for rule 2 (smaller scope) found
2020-01-13 17:16:32,349 # winner for rule 3 found
2020-01-13 17:16:32,349 # Winner is: fd01::1711:6b10:65fb:bc06
  • Scope(SA) = Scope(D) < Scope(SB): Scope(SA) wins
2020-01-13 17:17:02,592 #           inet6 addr: fd01::1711:6b10:65fb:bc06  scope: global  VAL
2020-01-13 17:17:02,596 #           inet6 addr: fe80::1711:6b10:65fb:bc06  scope: link  VAL
ping6 fe80::1711:6b10:65fb:bc06 
2020-01-13 17:17:08,035 #  ping6 fe80::1711:6b10:65fb:bc06
2020-01-13 17:17:08,037 # finding the best match within the source address candidates
2020-01-13 17:17:08,038 # Checking address: fd01::1711:6b10:65fb:bc06
2020-01-13 17:17:08,039 # winner for rule 2 (larger scope) found
2020-01-13 17:17:08,039 # winner for rule 3 found
2020-01-13 17:17:08,051 # Checking address: fe80::1711:6b10:65fb:bc06
2020-01-13 17:17:08,051 # Ease one - rule 1
  • Scope(SA) < Scope(D) = Scope(SB): Scope(SB) wins
2020-01-13 17:17:02,592 #           inet6 addr: fd01::1711:6b10:65fb:bc06  scope: global  VAL
2020-01-13 17:17:02,596 #           inet6 addr: fe80::1711:6b10:65fb:bc06  scope: link  VAL
2020-01-13 17:19:02,637 #  ping6 fd01::1711:6b10:65fb:bc06
2020-01-13 17:19:02,638 # finding the best match within the source address candidates
2020-01-13 17:19:02,639 # Checking address: fd01::1711:6b10:65fb:bc06
2020-01-13 17:19:02,639 # Ease one - rule 1

Multicast test, just to verify its returned correctly.

  • Scope(SA) < Scope(D) < Scope(SB): Scope(SB) wins
2020-01-13 17:17:02,592 #           inet6 addr: fd01::1711:6b10:65fb:bc06  scope: global  VAL
2020-01-13 17:17:02,596 #           inet6 addr: fe80::1711:6b10:65fb:bc06  scope: link  VAL
2020-01-13 17:25:15,148 #  ping6 ff04::1
2020-01-13 17:25:15,149 # finding the best match within the source address candidates
2020-01-13 17:25:15,149 # Checking address: fd01::1711:6b10:65fb:bc06
2020-01-13 17:25:15,149 # winner for rule 2 (larger scope) found
2020-01-13 17:25:15,150 # winner for rule 3 found
2020-01-13 17:25:15,150 # Checking address: fe80::1711:6b10:65fb:bc06
2020-01-13 17:25:15,150 # winner for rule 2 (smaller scope) found
2020-01-13 17:25:15,151 # winner for rule 3 found
2020-01-13 17:25:15,151 # Winner is: fd01::1711:6b10:65fb:bc06
  • Scope(SA) = Scope(D) < Scope(SB): Scope(SA) wins
2020-01-13 17:17:02,592 #           inet6 addr: fd01::1711:6b10:65fb:bc06  scope: global  VAL
2020-01-13 17:17:02,596 #           inet6 addr: fe80::1711:6b10:65fb:bc06  scope: link  VAL
2020-01-13 17:25:59,306 #  ping6 ff02::1
2020-01-13 17:25:59,309 # finding the best match within the source address candidates
2020-01-13 17:25:59,311 # Checking address: fd01::1711:6b10:65fb:bc06
2020-01-13 17:25:59,322 # winner for rule 2 (larger scope) found
2020-01-13 17:25:59,323 # winner for rule 3 found
2020-01-13 17:25:59,324 # Checking address: fe80::1711:6b10:65fb:bc06
2020-01-13 17:25:59,325 # winner for rule 2 (same scope) found
2020-01-13 17:25:59,325 # winner for rule 3 found
2020-01-13 17:25:59,326 # Winner is: fe80::1711:6b10:65fb:bc06

@fjmolinas
Copy link
Contributor

@miri64 Now its perfect! Please squash and split 03da7f1 in to its own commit.

Rule 2 of the source address algorithm outlined in [RFC6724] states the
possible source addresses must also be compared among each other:

>     Rule 2: Prefer appropriate scope.
>     If Scope(SA) < Scope(SB): If Scope(SA) < Scope(D), then prefer SB and
>     otherwise prefer SA.  Similarly, if Scope(SB) < Scope(SA): If
>     Scope(SB) < Scope(D), then prefer SA and otherwise prefer SB.

Our current implementation doesn't do that. It just checks if the scope
of a possible source is lesser than the scope of the destination
(which involves the second "If" in the rule).

This fix grants points according to the scope of an address. If the
scope matches, they get the highest points, ensuring that the selected
source will always be reachable from the destination.

[RFC6724]: https://tools.ietf.org/html/rfc6724
The comment exists since the introduction of the [original
implementation], but its meaning is unclear and misleading, as the code
doesn't do anything with link-local.

[original implementation]: RIOT-OS#3561
@miri64
Copy link
Member Author

miri64 commented Jan 14, 2020

Squashed.

@miri64 miri64 force-pushed the gnrc_netif/fix/highest-source-scope-wins branch from 1fc54f2 to 018e3dd Compare January 14, 2020 08:55
Copy link
Contributor

@fjmolinas fjmolinas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK!

@fjmolinas fjmolinas merged commit 1d206bc into RIOT-OS:master Jan 14, 2020
@miri64 miri64 deleted the gnrc_netif/fix/highest-source-scope-wins branch January 14, 2020 09:44
@miri64
Copy link
Member Author

miri64 commented Jan 14, 2020

🎉 Thanks for all testing and helping with the logic foobar of this PR @fjmolinas!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: network Area: Networking CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants