From: Claudio Jeker Subject: bgpd: improve MP capability negotiation To: tech@openbsd.org Date: Wed, 29 May 2024 11:55:57 +0200 Currently the BGP MP capability negotiation is not strict enough when systems present each other impossible combos. The moment one system sends the MP capability the session should no longer fall back to IPv4 unicast mode (as in pure RFC4271 mode). Instead it should accept that there is no negotiated AFI SAFI combo available and exchange nothing. For this to work we also need to handle unknown AFI SAFI pairs and mark them in capa.peer.mp so that we know that the MP capability was present in the OPEN message. For this use peer->capa.peer.mp[AID_UNSPEC] as a marker. In capa_neg_calc() only fall back to IPv4 unicast iff neither we nor the peer announced any MP capability. -- :wq Claudio Index: session.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/session.c,v diff -u -p -r1.478 session.c --- session.c 22 May 2024 08:41:14 -0000 1.478 +++ session.c 28 May 2024 15:22:16 -0000 @@ -2559,6 +2559,7 @@ parse_capabilities(struct peer *peer, st "Received multi protocol capability: " " unknown AFI %u, safi %u pair", afi, safi); + peer->capa.peer.mp[AID_UNSPEC] = 1; break; } peer->capa.peer.mp[aid] = 1; @@ -2715,12 +2716,14 @@ capa_neg_calc(struct peer *p) (p->capa.ann.as4byte && p->capa.peer.as4byte) != 0; /* MP: both side must agree on the AFI,SAFI pair */ + if (p->capa.peer.mp[AID_UNSPEC]) + hasmp = 1; for (i = AID_MIN; i < AID_MAX; i++) { if (p->capa.ann.mp[i] && p->capa.peer.mp[i]) p->capa.neg.mp[i] = 1; else p->capa.neg.mp[i] = 0; - if (p->capa.ann.mp[i]) + if (p->capa.ann.mp[i] || p->capa.peer.mp[i]) hasmp = 1; } /* if no MP capability present default to IPv4 unicast mode */