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");
> 

Reply via email to