Page MenuHomeFreeBSD

netinet6: make RFC4291 anycast conformance a sysctl
AcceptedPublic

Authored by ivy on Thu, May 1, 8:17 AM.

Details

Summary

in releases prior to 15.0 we followed RFC3513, which did not allow
sending any packets from an anycast address, by forbidding any attempt
to bind to an anycast address and rejecting incoming TCP connections to
a local anycast address.

recently this was changed to allow binding to an anycast address so that
UDP services could use an anycast address. however, TCP anycast was
still forbidden.

D50019 proposed removing the TCP restriction to allow full use of
anycast addresses by applications, but the consensus was that this is
too permissive and introduces the risk of a user configuring a stateful
service over an anycast address without understanding the implications.

however, we do want to permit TCP anycast for e.g. DNS servers, which
require both UDP and TCP, and where TCP anycast is in wide use at
scale[0]. so, introduce a new sysctl net.inet6.ip6.ip6_rfc4291_anycast,
which controls the behaviour of anycast addresses.

if the sysctl is set to 0, which is the default:

  • binding a UDP socket to an anycast address is permitted; this allows UDP services to receive data sent to an anycast address (e.g., for anycast monitoring or data collection services).
  • sending UDP packets with an anycast source address is forbidden.
  • binding a TCP socket to an anycast address is forbidden.
  • incoming TCP connections to an anycast address are rejected.

except for the first point, this largely matches the pre-15.0 behaviour,
but we now reject TCP connections with a RST rather than an ICMP error
because according to RFC4291 we're allowed to do that.

if the sysctl is set to 1:

  • outgoing UDP packets from an anycast address are permitted.
  • binding a TCP socket to an anycast address is permitted.
  • incoming TCP connections to an anycast address are permitted.

this allows the user to use anycast addresses for stateful protocols
when they understand the risks, but protects them from doing this
accidentally.

in both cases, raw sockets are treated the same as UDP, i.e. by default
they can receive traffic but not send it.

this does not change the default source selection logic: an anycast
address will never be chosen as the default source address. the user
has to explicitly bind the socket regardless of the sysctl setting.

document this behaviour in inet6.4, and add a pointer there from the
'anycast' option in ifconfig.8.

add some basic tests for TCP and raw sockets.

[0] https://www.ripe.net/publications/docs/ripe-393/

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 63817
Build 60701: arc lint + arc unit

Event Timeline

ivy requested review of this revision.Thu, May 1, 8:17 AM

add a couple of missing parentheses

This revision is now accepted and ready to land.Thu, May 1, 12:09 PM

Would it make sense to have also a setting where you allow anycast for UDP, but not for TCP?

sys/netinet6/in6_pcb.c
215

Why do you assume that TCP is equivalent to SOCK_STREAM? This is not true. For example, SCTP supports SOCK_STREAM sockets...

ziaee requested changes to this revision.Thu, May 1, 1:57 PM

Small nit

sbin/ifconfig/ifconfig.8
458

Then this link becomes clickable in man.freebsd.org or gnome help or whatever.

This revision now requires changes to proceed.Thu, May 1, 1:57 PM
sbin/ifconfig/ifconfig.8
458

I would expect that link to be broken? It's cross-referencing a section from another manpage, not one within this manpage. I don't see how whatever's generating the page would actually get the correct address.

sys/netinet6/in6_pcb.c
215

the intent is to disallow anything that's not UDP or raw sockets. aiui, we should also prohibit SCTP here. so, does the code seem correct if i adjust the comment?

it was not immediately clear to me how to get the actual protocol from an inpcb, since inp_ip_p doesn't seem to be set at this point.

ziaee added inline comments.
sbin/ifconfig/ifconfig.8
458

Excuse me, I was incorrect. Looking at mdoc(7) again it says clearly Reference a section or subsection in the same manual page.

(I also incorrectly thought that "Resign as Reviewer" would remove the "Needs Revision" without marking it to claim that I reviewed this, since I did not contribute anything to this one, my apologies)

This revision is now accepted and ready to land.Thu, May 1, 3:36 PM