<div dir="ltr">Hi Ivan,<br><br>You make a lot of compelling points there, and I'm inclined to follow your advice. The (untested) patch to change this to the behavior you'd like is actually this trivial two line change:<br><br><div>diff --git a/src/routingtable.c b/src/routingtable.c</div><div>index f9c3eff..0ad4d3c 100644</div><div>--- a/src/routingtable.c</div><div>+++ b/src/routingtable.c</div><div>@@ -194,6 +194,8 @@ static int add(struct routing_table_node __rcu **trie, u8 bits, const u8 *key, u</div><div> <span style="white-space:pre">           </span>return 0;</div><div> <span style="white-space:pre">   </span>}</div><div> <span style="white-space:pre">   </span>if (node_placement(*trie, key, cidr, bits, &node, lock)) {</div><div>+<span style="white-space:pre">               </span>if (node->peer)</div><div>+<span style="white-space:pre">                   </span>return -EEXIST;</div><div> <span style="white-space:pre">             </span>node->peer = peer;</div><div> <span style="white-space:pre">               </span>return 0;</div><div> <span style="white-space:pre">   </span>}</div><div><br></div><div>I'm especially compelled by your point that this would mirror the semantics of the routing table.</div><div><br></div><div>However, I was a bit confused by your mention of a race condition, because I believe that my current solution _avoids_ a race condition. The routing table has a concept of metrics, which allows for avoiding a race condition when gracefully handing over routes between different interfaces, like this:</div><div><br></div><div># ip route add <a href="http://10.0.0.0/24">10.0.0.0/24</a> dev eth0 metric 1000</div><div># ip route add <a href="http://10.0.0.0/24">10.0.0.0/24</a> dev wlan0 metric 1001</div><div># ip route del <a href="http://10.0.0.0/24">10.0.0.0/24</a> dev eth0 metric 1000<br></div><div><br></div><div>(It also has `ip route change`, but I don't know if this is actually implemented in a race free way in the kernel or how it works.)</div><div><br></div><div>If I added the -EEXIST semantic to WireGuard's allowed-ips, if you wanted to change traffic from one peer to the other, you could not do so without dropping a bunch of packets during the interim. Thus, a race condition. This was the original reason for designing it as I did -- I liked the idea of race-free handovers.</div><div><br></div><div>Do you think maintaining race-free handover is important enough to warrant not using -EEXIST? I sort of think it is important. Of course, I could add an explicit "change" flag, but that makes things a bit complicated. And, in the case of your hypothetical fat-fingered sysadmin, the error condition is that this "fails closed", rather than "fails open", which probably makes it not such a big deal.</div><div><br></div><div>What do you think of that argumentation?</div><div><br></div><div>Jason</div></div>