So one of the things relayd's snmp agentx hook provieds is the relay sessions. To do that every connection accepted by relayd does 2 IMSG and the pfe is using linear lists to track them. Because of this the PFE engine is using more CPU time than needed.
Is anyone using the fast changing session data in snmp? Else I propose to remove the code. -- :wq Claudio ? obj Index: pfe.c =================================================================== RCS file: /cvs/src/usr.sbin/relayd/pfe.c,v retrieving revision 1.89 diff -u -p -r1.89 pfe.c --- pfe.c 28 May 2017 10:39:15 -0000 1.89 +++ pfe.c 28 Nov 2017 18:45:31 -0000 @@ -252,9 +252,8 @@ pfe_dispatch_relay(int fd, struct privse struct ctl_stats crs; struct relay *rlay; struct ctl_conn *c; - struct rsession con, *s, *t; + struct rsession con; int cid; - objid_t sid; switch (imsg->hdr.type) { case IMSG_NATLOOK: @@ -305,38 +304,6 @@ pfe_dispatch_relay(int fd, struct privse /* Last ack for a previous request */ imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0); - } - break; - case IMSG_SESS_PUBLISH: - IMSG_SIZE_CHECK(imsg, s); - if ((s = calloc(1, sizeof(*s))) == NULL) - return (0); /* XXX */ - memcpy(s, imsg->data, sizeof(*s)); - TAILQ_FOREACH(t, &env->sc_sessions, se_entry) { - /* duplicate registration */ - if (t->se_id == s->se_id) { - free(s); - return (0); - } - if (t->se_id > s->se_id) - break; - } - if (t) - TAILQ_INSERT_BEFORE(t, s, se_entry); - else - TAILQ_INSERT_TAIL(&env->sc_sessions, s, se_entry); - break; - case IMSG_SESS_UNPUBLISH: - IMSG_SIZE_CHECK(imsg, &sid); - memcpy(&sid, imsg->data, sizeof(sid)); - TAILQ_FOREACH(s, &env->sc_sessions, se_entry) - if (s->se_id == sid) - break; - if (s) { - TAILQ_REMOVE(&env->sc_sessions, s, se_entry); - free(s); - } else { - DPRINTF("removal of unpublished session %i", sid); } break; default: Index: relay.c =================================================================== RCS file: /cvs/src/usr.sbin/relayd/relay.c,v retrieving revision 1.236 diff -u -p -r1.236 relay.c --- relay.c 28 Nov 2017 01:51:47 -0000 1.236 +++ relay.c 28 Nov 2017 18:45:32 -0000 @@ -328,19 +328,6 @@ relay_init(struct privsep *ps, struct pr } void -relay_session_publish(struct rsession *s) -{ - proc_compose(env->sc_ps, PROC_PFE, IMSG_SESS_PUBLISH, s, sizeof(*s)); -} - -void -relay_session_unpublish(struct rsession *s) -{ - proc_compose(env->sc_ps, PROC_PFE, IMSG_SESS_UNPUBLISH, - &s->se_id, sizeof(s->se_id)); -} - -void relay_statistics(int fd, short events, void *arg) { struct privsep *ps = arg; @@ -1120,7 +1107,6 @@ relay_accept(int fd, short event, void * relay_sessions++; SPLAY_INSERT(session_tree, &rlay->rl_sessions, con); - relay_session_publish(con); /* Increment the per-relay session counter */ rlay->rl_stats[ps->ps_instance].last++; @@ -1667,7 +1653,6 @@ relay_close(struct rsession *con, const struct protocol *proto = rlay->rl_proto; SPLAY_REMOVE(session_tree, &rlay->rl_sessions, con); - relay_session_unpublish(con); event_del(&con->se_ev); if (con->se_in.bev != NULL) Index: relay_udp.c =================================================================== RCS file: /cvs/src/usr.sbin/relayd/relay_udp.c,v retrieving revision 1.47 diff -u -p -r1.47 relay_udp.c --- relay_udp.c 4 Jul 2017 19:59:51 -0000 1.47 +++ relay_udp.c 28 Nov 2017 18:45:32 -0000 @@ -275,7 +275,6 @@ relay_udp_server(int fd, short sig, void relay_sessions++; SPLAY_INSERT(session_tree, &rlay->rl_sessions, con); - relay_session_publish(con); /* Increment the per-relay session counter */ rlay->rl_stats[ps->ps_instance].last++; Index: relayd.c =================================================================== RCS file: /cvs/src/usr.sbin/relayd/relayd.c,v retrieving revision 1.170 diff -u -p -r1.170 relayd.c --- relayd.c 27 Nov 2017 21:06:26 -0000 1.170 +++ relayd.c 28 Nov 2017 18:45:33 -0000 @@ -182,7 +182,6 @@ main(int argc, char *argv[]) env->sc_conffile = conffile; env->sc_conf.opts = opts; TAILQ_INIT(&env->sc_hosts); - TAILQ_INIT(&env->sc_sessions); env->sc_rtable = getrtable(); /* initialize the TLS session id to a random key for all relay procs */ arc4random_buf(env->sc_conf.tls_sid, sizeof(env->sc_conf.tls_sid)); Index: relayd.h =================================================================== RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v retrieving revision 1.248 diff -u -p -r1.248 relayd.h --- relayd.h 28 Nov 2017 18:25:53 -0000 1.248 +++ relayd.h 28 Nov 2017 18:45:33 -0000 @@ -971,8 +971,6 @@ enum imsg_type { IMSG_CFG_DONE, IMSG_CA_PRIVENC, IMSG_CA_PRIVDEC, - IMSG_SESS_PUBLISH, /* from relay to pfe */ - IMSG_SESS_UNPUBLISH, IMSG_TLSTICKET_REKEY }; @@ -1080,7 +1078,6 @@ struct relayd { struct routerlist *sc_rts; struct netroutelist *sc_routes; struct ca_pkeylist *sc_pkeys; - struct sessionlist sc_sessions; char sc_demote_group[IFNAMSIZ]; u_int16_t sc_id; int sc_rtable; @@ -1209,8 +1206,6 @@ void relay_match(struct kvlist *, struc struct kvtree *); void relay_session_insert(struct rsession *); void relay_session_remove(struct rsession *); -void relay_session_publish(struct rsession *); -void relay_session_unpublish(struct rsession *); SPLAY_PROTOTYPE(session_tree, rsession, se_nodes, relay_session_cmp); Index: snmp.c =================================================================== RCS file: /cvs/src/usr.sbin/relayd/snmp.c,v retrieving revision 1.29 diff -u -p -r1.29 snmp.c --- snmp.c 28 May 2017 10:39:15 -0000 1.29 +++ snmp.c 28 Nov 2017 18:45:33 -0000 @@ -88,8 +88,6 @@ struct router * snmp_router_byidx(struct relayd *, u_int *, u_int *, u_int, u_int); struct relay * snmp_relay_byidx(struct relayd *, u_int *, u_int *, u_int, u_int); -struct rsession * - snmp_session_byidx(struct relayd *, u_int *, u_int *, u_int, u_int); struct rdr * snmp_rdr_byidx(struct relayd *, u_int *, u_int *, u_int, u_int); struct netroute * @@ -105,8 +103,6 @@ int snmp_netroute(struct relayd *, stru int, uint32_t, uint32_t, u_int); int snmp_host(struct relayd *, struct snmp_oid *, struct agentx_pdu *, int, uint32_t, uint32_t, u_int); -int snmp_session(struct relayd *, struct snmp_oid *, struct agentx_pdu *, - int, uint32_t, uint32_t, u_int); int snmp_table(struct relayd *, struct snmp_oid *, struct agentx_pdu *, int, uint32_t, uint32_t, u_int); @@ -437,21 +433,6 @@ snmp_agentx_process(struct agentx_handle oid.o_id[OIDIDX_relaydInfo + 1] = 0; oid.o_id[OIDIDX_relaydInfo + 2] = 0; /* FALLTHROUGH */ - case 6: - log_warnx("%s: sessions", __func__); - if (infoendidx < 6) - break; - if (snmp_session(env, &oid, resp, getnext, - infoentryendidx, infoentryidxendidx, - sr.include) == 0) - break; - if (!getnext) - goto nosuchinstance; - - oid.o_id[OIDIDX_relaydInfo] = 7; - oid.o_id[OIDIDX_relaydInfo + 1] = 0; - oid.o_id[OIDIDX_relaydInfo + 2] = 0; - /* FALLTHROUGH */ case 7: log_warnx("%s: tables", __func__); if (infoendidx < 7) @@ -1016,56 +997,6 @@ snmp_host_byidx(struct relayd *env, u_in return (NULL); } -struct rsession * -snmp_session_byidx(struct relayd *env, u_int *instanceidx, u_int *objectidx, - u_int getnext, u_int include) -{ - struct rsession *session; - - if (*objectidx > SESSION_MAX_SUBIDX) - return (NULL); - if (*objectidx == 0) { - if (!getnext) - return (NULL); - *objectidx = 1; - } - - restart: - TAILQ_FOREACH(session, &env->sc_sessions, se_entry) { - if (session->se_id >= *instanceidx) { - if (getnext) { - /* Lexographical ordering */ - - /* 1) try the next instance index */ - if (session->se_id == *instanceidx && !include) - session = TAILQ_NEXT(session, se_entry); - if (session) { - *instanceidx = session->se_id; - return (session); - } - - /* 2) try the next object index */ - if (*objectidx < SESSION_MAX_SUBIDX) { - *objectidx += 1; - *instanceidx = 1; - include = 1; - goto restart; - } - - /* 3) no further OIDs under this prefix */ - return (NULL); - } - - if (session->se_id == *instanceidx) - return (session); - - return (NULL); - } - } - - return (NULL); -} - struct table * snmp_table_byidx(struct relayd *env, u_int *instanceidx, u_int *objectidx, u_int getnext, u_int include) @@ -1554,132 +1485,6 @@ snmp_host(struct relayd *env, struct snm break; default: fatalx("unhandled host element id"); - } - - return (0); -} - -int -snmp_session(struct relayd *env, struct snmp_oid *oid, struct agentx_pdu *resp, - int getnext, uint32_t einstanceidx, uint32_t eobjectidx, u_int include) -{ - struct timeval tv, now; - time_t ticks; - struct rsession *session; - u_int instanceidx, objectidx; - u_int32_t status, pid, port, addrtype; - - instanceidx = oid->o_id[OIDIDX_relaydInfo + 2]; - objectidx = oid->o_id[OIDIDX_relaydInfo + 1]; - session = snmp_session_byidx(env, &instanceidx, &objectidx, getnext, - include); - if (session == NULL) - return (-1); - - if (instanceidx >= einstanceidx || objectidx >= eobjectidx) - return (0); - - oid->o_id[OIDIDX_relaydInfo + 1] = objectidx; - oid->o_id[OIDIDX_relaydInfo + 2] = instanceidx; - - switch (objectidx) { - case 1: /* index */ - if (snmp_agentx_varbind(resp, oid, - AGENTX_INTEGER, &session->se_id, - sizeof(session->se_id)) == -1) - return (-1); - break; - case 2: /* relay index */ - if (snmp_agentx_varbind(resp, oid, - AGENTX_INTEGER, &session->se_relayid, - sizeof(session->se_relayid)) == -1) - return (-1); - break; - case 3: /* in address */ - if (snmp_agentx_varbind(resp, oid, - AGENTX_OCTET_STRING, sstodata(&session->se_in.ss), - sstolen(&session->se_in.ss)) == -1) - return (-1); - break; - case 4: /* in address type */ - if (session->se_in.ss.ss_family == AF_INET) - addrtype = 1; - else if (session->se_in.ss.ss_family == AF_INET6) - addrtype = 2; - if (snmp_agentx_varbind(resp, oid, - AGENTX_INTEGER, &addrtype, - sizeof(addrtype)) == -1) - return (-1); - break; - case 5: /* out address */ - if (snmp_agentx_varbind(resp, oid, - AGENTX_OCTET_STRING, sstodata(&session->se_out.ss), - sstolen(&session->se_out.ss)) == -1) - return (-1); - break; - case 6: /* out address type */ - if (session->se_out.ss.ss_family == AF_INET) - addrtype = 1; - else if (session->se_out.ss.ss_family == AF_INET6) - addrtype = 2; - if (snmp_agentx_varbind(resp, oid, - AGENTX_INTEGER, &addrtype, - sizeof(addrtype)) == -1) - return (-1); - break; - case 7: /* port out */ - port = session->se_out.port; - if (snmp_agentx_varbind(resp, oid, - AGENTX_INTEGER, &port, - sizeof(port)) == -1) - return (-1); - break; - case 8: /* port in */ - port = session->se_in.port; - if (snmp_agentx_varbind(resp, oid, - AGENTX_INTEGER, &port, - sizeof(port)) == -1) - return (-1); - break; - case 9: /* age */ - getmonotime(&now); - timerclear(&tv); - timersub(&now, &session->se_tv_start, &tv); - ticks = tv.tv_sec * 100 + tv.tv_usec / 10000; - if (snmp_agentx_varbind(resp, oid, - AGENTX_INTEGER, &ticks, - sizeof(ticks)) == -1) - return (-1); - break; - case 10: /* idle time */ - getmonotime(&now); - timerclear(&tv); - timersub(&now, &session->se_tv_last, &tv); - ticks = tv.tv_sec * 100 + tv.tv_usec / 10000; - if (snmp_agentx_varbind(resp, oid, - AGENTX_INTEGER, &ticks, - sizeof(ticks)) == -1) - return (-1); - break; - case 11: /* status */ - if (session->se_done) - status = 1; - else - status = 0; - if (snmp_agentx_varbind(resp, oid, - AGENTX_INTEGER, &status, - sizeof(status)) == -1) - return (-1); - break; - case 12: /* session pid */ - pid = (u_int32_t)session->se_pid; - if (snmp_agentx_varbind(resp, oid, - AGENTX_INTEGER, &pid, - sizeof(pid)) == -1) - return (-1); - break; - default: - fatalx("unhandled table element id"); } return (0);