BGP doesn't use TCP keepalive, it uses its own keepalive mechanism. My question is why can't bgp turn-on the SO_KEEPaLIVE of TCP and live happily? why does it not use tcp keepalive and implement its own keepalive ?
TCP "keepalive" is a feature that is not present on all operating systems. It is not in the TCP standard itself and it's not reliable. RC1122 specifes it, but explicitly states:
Implementors MAY include "keep-alives" in their TCP implementations, although this practice is not universally accepted. If keep-alives are included, the application MUST be able to turn them on or off for each TCP connection, and they MUST default to off.
Even more important:
It is extremely important to remember that ACK segments that contain no data are not reliably transmitted by TCP. Consequently, if a keep-alive mechanism is implemented it MUST NOT interpret failure to respond to any specific probe as a dead connection.
TCP keepalive uses the TCP protocol in a special way, sending a duplicate ACK with no data attached to it. Thing is: You can't count on it being available. Also some firewalls filter TCP keepalives.
For BGP to function correctly you need a way to implement specific timers for keepalive (how often do we send a message) and hold (after which time do we declare a peer to be non-responsive) that are reliably sent. So BGP is using it's own keepalive message which is not a lot of overhead (19 bytes) compared to TCP keepalive.