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