On Tue, Dec 27, 2022 at 05:44:39PM +0100, Claudio Jeker wrote: > The role capability only works on ebgp sessions. It makes no sense on > ibgp sessions and the RFC 9234 does not define any behaviour for that. > I decided to: > - Exclude the role capability for ibgp sessions when sending an OPEN > - Warn when a role capability is received on an iBGP session > - Make sure the capability negotiation is skipped for ibgp sessions, > this disables the role capability on the session. > > I kept the peer capability intact so that it shows in bgpctl show nei > output. > > This diff also includes the necessary bit in the notification handling for > capabilities (I forgot to add CAPA_ROLE there in the initial diff).
ok (two tiny nits below) > -- > :wq Claudio > > Index: session.c > =================================================================== > RCS file: /cvs/src/usr.sbin/bgpd/session.c,v > retrieving revision 1.436 > diff -u -p -r1.436 session.c > --- session.c 18 Oct 2022 12:24:51 -0000 1.436 > +++ session.c 27 Dec 2022 16:41:29 -0000 > @@ -1441,8 +1441,8 @@ session_open(struct peer *p) > if (p->capa.ann.refresh) /* no data */ > errs += session_capa_add(opb, CAPA_REFRESH, 0); > > - /* BGP open policy, RFC 9234 */ > - if (p->capa.ann.role_ena) { > + /* BGP open policy, RFC 9234, only for ebgp sessions */ > + if (p->capa.ann.role_ena && p->conf.ebgp) { > errs += session_capa_add(opb, CAPA_ROLE, 1); > errs += ibuf_add(opb, &p->capa.ann.role, 1); > } > @@ -2478,6 +2478,11 @@ parse_notification(struct peer *peer) > log_peer_warnx(&peer->conf, > "disabling route refresh capability"); > break; > + case CAPA_ROLE: > + peer->capa.ann.role_ena = 0; > + log_peer_warnx(&peer->conf, > + "disabling role capability"); > + break; > case CAPA_RESTART: > peer->capa.ann.grestart.restart = 0; > log_peer_warnx(&peer->conf, > @@ -2616,10 +2621,13 @@ parse_capabilities(struct peer *peer, u_ > case CAPA_ROLE: > if (capa_len != 1) { > log_peer_warnx(&peer->conf, > - "Bad open policy capability length: " > + "Bad role capability length: " > "%u", capa_len); you could merge the "%u" into the previous line > break; > } > + if (!peer->conf.ebgp) > + log_peer_warnx(&peer->conf, > + "Received role capability on iBGP session"); > peer->capa.peer.role_ena = 1; > peer->capa.peer.role = *capa_val; > break; > @@ -2835,8 +2843,10 @@ capa_neg_calc(struct peer *p, uint8_t *s > * Make sure that the roles match and set the negotiated capability > * to the role of the peer. So the RDE can inject the OTC attribute. > * See RFC 9234, section 4.2. > + * These check should only happen on ebgp sessions. checks > */ > - if (p->capa.ann.role_ena != 0 && p->capa.peer.role_ena != 0) { > + if (p->capa.ann.role_ena != 0 && p->capa.peer.role_ena != 0 && > + p->conf.ebgp) { > switch (p->capa.ann.role) { > case CAPA_ROLE_PROVIDER: > if (p->capa.peer.role != CAPA_ROLE_CUSTOMER) > @@ -2868,7 +2878,7 @@ capa_neg_calc(struct peer *p, uint8_t *s > } > p->capa.neg.role_ena = 1; > p->capa.neg.role = p->capa.peer.role; > - } else if (p->capa.ann.role_ena == 2) { > + } else if (p->capa.ann.role_ena == 2 && p->conf.ebgp) { > /* enforce presence of open policy role capability */ > log_peer_warnx(&p->conf, "open policy role enforced but " > "not present"); >