On Fri, Dec 13, 2019 at 05:18:17PM +0100, Claudio Jeker wrote:
> This diff changes the way session or peer related imsgs are handled.
> Instead of passing the imsg.hdr.peerid down and doing the lookup for the
> peer in each function move that code up into the imsg handler.
> The plan is to add an imsg queue per peer later on to make the processing
> of messages more fair than what happens currently.
> 
> While there change some fatalx to warnx since it is fine to just ignore
> bad GR restart messages.
> 
> OK?

OK denis@

> -- 
> :wq Claudio
> 
> Index: rde.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
> retrieving revision 1.492
> diff -u -p -r1.492 rde.c
> --- rde.c     13 Dec 2019 14:10:56 -0000      1.492
> +++ rde.c     13 Dec 2019 15:09:09 -0000
> @@ -49,7 +49,7 @@
>  void          rde_sighdlr(int);
>  void          rde_dispatch_imsg_session(struct imsgbuf *);
>  void          rde_dispatch_imsg_parent(struct imsgbuf *);
> -int           rde_update_dispatch(struct imsg *);
> +void          rde_update_dispatch(struct rde_peer *, struct imsg *);
>  int           rde_update_update(struct rde_peer *, struct filterstate *,
>                    struct bgpd_addr *, u_int8_t);
>  void          rde_update_withdraw(struct rde_peer *, struct bgpd_addr *,
> @@ -98,11 +98,11 @@ void               peer_shutdown(void);
>  int           peer_localaddrs(struct rde_peer *, struct bgpd_addr *);
>  struct rde_peer *peer_match(struct ctl_neighbor *, u_int32_t);
>  struct rde_peer      *peer_add(u_int32_t, struct peer_config *);
> -void          peer_up(u_int32_t, struct session_up *);
> -void          peer_down(u_int32_t);
> +void          peer_up(struct rde_peer *, struct session_up *);
> +void          peer_down(struct rde_peer *);
>  void          peer_flush(struct rde_peer *, u_int8_t, time_t);
> -void          peer_stale(u_int32_t, u_int8_t);
> -void          peer_dump(u_int32_t, u_int8_t);
> +void          peer_stale(struct rde_peer *, u_int8_t);
> +void          peer_dump(struct rde_peer *, u_int8_t);
>  static void   peer_recv_eor(struct rde_peer *, u_int8_t);
>  static void   peer_send_eor(struct rde_peer *, u_int8_t);
>  
> @@ -380,7 +380,12 @@ rde_dispatch_imsg_session(struct imsgbuf
>  
>               switch (imsg.hdr.type) {
>               case IMSG_UPDATE:
> -                     rde_update_dispatch(&imsg);
> +                     if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
> +                             log_warnx("rde_dispatch: unknown peer id %d",
> +                                 imsg.hdr.peerid);
> +                             break;
> +                     }
> +                     rde_update_dispatch(peer, &imsg);
>                       break;
>               case IMSG_SESSION_ADD:
>                       if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(pconf))
> @@ -392,10 +397,20 @@ rde_dispatch_imsg_session(struct imsgbuf
>                       if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(sup))
>                               fatalx("incorrect size of session request");
>                       memcpy(&sup, imsg.data, sizeof(sup));
> -                     peer_up(imsg.hdr.peerid, &sup);
> +                     if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
> +                             log_warnx("rde_dispatch: unknown peer id %d",
> +                                 imsg.hdr.peerid);
> +                             break;
> +                     }
> +                     peer_up(peer, &sup);
>                       break;
>               case IMSG_SESSION_DOWN:
> -                     peer_down(imsg.hdr.peerid);
> +                     if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
> +                             log_warnx("rde_dispatch: unknown peer id %d",
> +                                 imsg.hdr.peerid);
> +                             break;
> +                     }
> +                     peer_down(peer);
>                       break;
>               case IMSG_SESSION_STALE:
>                       if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(aid)) {
> @@ -403,9 +418,16 @@ rde_dispatch_imsg_session(struct imsgbuf
>                               break;
>                       }
>                       memcpy(&aid, imsg.data, sizeof(aid));
> -                     if (aid >= AID_MAX)
> -                             fatalx("IMSG_SESSION_STALE: bad AID");
> -                     peer_stale(imsg.hdr.peerid, aid);
> +                     if (aid >= AID_MAX) {
> +                             log_warnx("IMSG_SESSION_STALE: bad AID");
> +                             break;
> +                     }
> +                     if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
> +                             log_warnx("rde_dispatch: unknown peer id %d",
> +                                 imsg.hdr.peerid);
> +                             break;
> +                     }
> +                     peer_stale(peer, aid);
>                       break;
>               case IMSG_SESSION_FLUSH:
>                       if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(aid)) {
> @@ -413,8 +435,10 @@ rde_dispatch_imsg_session(struct imsgbuf
>                               break;
>                       }
>                       memcpy(&aid, imsg.data, sizeof(aid));
> -                     if (aid >= AID_MAX)
> -                             fatalx("IMSG_SESSION_FLUSH: bad AID");
> +                     if (aid >= AID_MAX) {
> +                             log_warnx("IMSG_SESSION_FLUSH: bad AID");
> +                             break;
> +                     }
>                       if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
>                               log_warnx("rde_dispatch: unknown peer id %d",
>                                   imsg.hdr.peerid);
> @@ -428,8 +452,10 @@ rde_dispatch_imsg_session(struct imsgbuf
>                               break;
>                       }
>                       memcpy(&aid, imsg.data, sizeof(aid));
> -                     if (aid >= AID_MAX)
> -                             fatalx("IMSG_SESSION_RESTARTED: bad AID");
> +                     if (aid >= AID_MAX) {
> +                             log_warnx("IMSG_SESSION_RESTARTED: bad AID");
> +                             break;
> +                     }
>                       if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
>                               log_warnx("rde_dispatch: unknown peer id %d",
>                                   imsg.hdr.peerid);
> @@ -444,9 +470,16 @@ rde_dispatch_imsg_session(struct imsgbuf
>                               break;
>                       }
>                       memcpy(&aid, imsg.data, sizeof(aid));
> -                     if (aid >= AID_MAX)
> -                             fatalx("IMSG_REFRESH: bad AID");
> -                     peer_dump(imsg.hdr.peerid, aid);
> +                     if (aid >= AID_MAX) {
> +                             log_warnx("IMSG_REFRESH: bad AID");
> +                             break;
> +                     }
> +                     if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
> +                             log_warnx("rde_dispatch: unknown peer id %d",
> +                                 imsg.hdr.peerid);
> +                             break;
> +                     }
> +                     peer_dump(peer, aid);
>                       break;
>               case IMSG_NETWORK_ADD:
>                       if (imsg.hdr.len - IMSG_HEADER_SIZE !=
> @@ -1022,13 +1055,12 @@ rde_dispatch_imsg_parent(struct imsgbuf 
>  }
>  
>  /* handle routing updates from the session engine. */
> -int
> -rde_update_dispatch(struct imsg *imsg)
> +void
> +rde_update_dispatch(struct rde_peer *peer, struct imsg *imsg)
>  {
>       struct filterstate       state;
>       struct bgpd_addr         prefix;
>       struct mpattr            mpa;
> -     struct rde_peer         *peer;
>       u_char                  *p, *mpp = NULL;
>       int                      error = -1, pos = 0;
>       u_int16_t                afi, len, mplen;
> @@ -1038,17 +1070,11 @@ rde_update_dispatch(struct imsg *imsg)
>       u_int8_t                 aid, prefixlen, safi, subtype;
>       u_int32_t                fas;
>  
> -     peer = peer_get(imsg->hdr.peerid);
> -     if (peer == NULL)       /* unknown peer, cannot happen */
> -             return (-1);
> -     if (peer->state != PEER_UP)
> -             return (-1);    /* peer is not yet up, cannot happen */
> -
>       p = imsg->data;
>  
>       if (imsg->hdr.len < IMSG_HEADER_SIZE + 2) {
>               rde_update_err(peer, ERR_UPDATE, ERR_UPD_ATTRLIST, NULL, 0);
> -             return (-1);
> +             return;
>       }
>  
>       memcpy(&len, p, 2);
> @@ -1056,7 +1082,7 @@ rde_update_dispatch(struct imsg *imsg)
>       p += 2;
>       if (imsg->hdr.len < IMSG_HEADER_SIZE + 2 + withdrawn_len + 2) {
>               rde_update_err(peer, ERR_UPDATE, ERR_UPD_ATTRLIST, NULL, 0);
> -             return (-1);
> +             return;
>       }
>  
>       p += withdrawn_len;
> @@ -1066,7 +1092,7 @@ rde_update_dispatch(struct imsg *imsg)
>       if (imsg->hdr.len <
>           IMSG_HEADER_SIZE + 2 + withdrawn_len + 2 + attrpath_len) {
>               rde_update_err(peer, ERR_UPDATE, ERR_UPD_ATTRLIST, NULL, 0);
> -             return (-1);
> +             return;
>       }
>  
>       nlri_len =
> @@ -1078,12 +1104,12 @@ rde_update_dispatch(struct imsg *imsg)
>                       /* crap at end of update which should not be there */
>                       rde_update_err(peer, ERR_UPDATE,
>                           ERR_UPD_ATTRLIST, NULL, 0);
> -                     return (-1);
> +                     return;
>               }
>               if (withdrawn_len == 0) {
>                       /* EoR marker */
>                       peer_recv_eor(peer, AID_INET);
> -                     return (0);
> +                     return;
>               }
>       }
>  
> @@ -1394,8 +1420,6 @@ rde_update_dispatch(struct imsg *imsg)
>  done:
>       rde_filterstate_clean(&state);
>       rde_send_pftable_commit();
> -
> -     return (error);
>  }
>  
>  int
> @@ -3290,7 +3314,7 @@ rde_softreconfig_in_done(void *arg, u_in
>                       /* dump the full table to neighbors that changed rib */
>                       for (aid = 0; aid < AID_MAX; aid++) {
>                               if (peer->capa.mp[aid])
> -                                     peer_dump(peer->conf.id, aid);
> +                                     peer_dump(peer, aid);
>                       }
>               }
>       }
> @@ -3711,17 +3735,10 @@ peer_adjout_stale_upcall(struct prefix *
>  }
>  
>  void
> -peer_up(u_int32_t id, struct session_up *sup)
> +peer_up(struct rde_peer *peer, struct session_up *sup)
>  {
> -     struct rde_peer *peer;
>       u_int8_t         i;
>  
> -     peer = peer_get(id);
> -     if (peer == NULL) {
> -             log_warnx("peer_up: unknown peer id %d", id);
> -             return;
> -     }
> -
>       if (peer->state == PEER_ERR) {
>               /*
>                * There is a race condition when doing PEER_ERR -> PEER_DOWN.
> @@ -3742,7 +3759,8 @@ peer_up(u_int32_t id, struct session_up 
>  
>       if (peer_localaddrs(peer, &sup->local_addr)) {
>               peer->state = PEER_DOWN;
> -             imsg_compose(ibuf_se, IMSG_SESSION_DOWN, id, 0, -1, NULL, 0);
> +             imsg_compose(ibuf_se, IMSG_SESSION_DOWN, peer->conf.id, 0, -1,
> +                 NULL, 0);
>               return;
>       }
>  
> @@ -3750,20 +3768,13 @@ peer_up(u_int32_t id, struct session_up 
>  
>       for (i = 0; i < AID_MAX; i++) {
>               if (peer->capa.mp[i])
> -                     peer_dump(id, i);
> +                     peer_dump(peer, i);
>       }
>  }
>  
>  void
> -peer_down(u_int32_t id)
> +peer_down(struct rde_peer *peer)
>  {
> -     struct rde_peer         *peer;
> -
> -     peer = peer_get(id);
> -     if (peer == NULL) {
> -             log_warnx("peer_down: unknown peer id %d", id);
> -             return;
> -     }
>       peer->remote_bgpid = 0;
>       peer->state = PEER_DOWN;
>       /* stop all pending dumps which may depend on this peer */
> @@ -3858,17 +3869,10 @@ peer_flush(struct rde_peer *peer, u_int8
>  }
>  
>  void
> -peer_stale(u_int32_t id, u_int8_t aid)
> +peer_stale(struct rde_peer *peer, u_int8_t aid)
>  {
> -     struct rde_peer         *peer;
>       time_t                   now;
>  
> -     peer = peer_get(id);
> -     if (peer == NULL) {
> -             log_warnx("peer_stale: unknown peer id %d", id);
> -             return;
> -     }
> -
>       /* flush the now even staler routes out */
>       if (peer->staletime[aid])
>               peer_flush(peer, aid, peer->staletime[aid]);
> @@ -3887,16 +3891,8 @@ peer_stale(u_int32_t id, u_int8_t aid)
>  }
>  
>  void
> -peer_dump(u_int32_t id, u_int8_t aid)
> +peer_dump(struct rde_peer *peer, u_int8_t aid)
>  {
> -     struct rde_peer         *peer;
> -
> -     peer = peer_get(id);
> -     if (peer == NULL) {
> -             log_warnx("peer_dump: unknown peer id %d", id);
> -             return;
> -     }
> -
>       if (peer->conf.export_type == EXPORT_NONE) {
>               /* nothing to send apart from the marker */
>               if (peer->capa.grestart.restart)
> @@ -4220,7 +4216,7 @@ rde_shutdown(void)
>       /* First all peers go down */
>       for (i = 0; i <= peertable.peer_hashmask; i++)
>               while ((p = LIST_FIRST(&peertable.peer_hashtbl[i])) != NULL)
> -                     peer_down(p->conf.id);
> +                     peer_down(p);
>  
>       /* free filters */
>       filterlist_free(out_rules);
> 

Reply via email to