From 4c73aa256c12c08a7f5e4841cb669d5708866c31 Mon Sep 17 00:00:00 2001 From: purplerain Date: Sat, 9 Dec 2023 19:58:49 +0000 Subject: [PATCH] sync with OpenBSD -current --- include/tib.h | 3 +- sys/dev/pv/if_vio.c | 32 ++++++++++++++++++-- sys/net/if_pflow.c | 56 +++++++++++++++++++++++++++++++---- sys/net/if_pflow.h | 37 +++++++++++++---------- usr.sbin/rpki-client/parser.c | 31 +++++++++++++++---- 5 files changed, 129 insertions(+), 30 deletions(-) diff --git a/include/tib.h b/include/tib.h index 97dc08cdc..313745f8c 100644 --- a/include/tib.h +++ b/include/tib.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tib.h,v 1.9 2022/12/27 07:44:56 jmc Exp $ */ +/* $OpenBSD: tib.h,v 1.10 2023/12/08 19:14:36 miod Exp $ */ /* * Copyright (c) 2011,2014 Philip Guenther * @@ -216,6 +216,7 @@ struct tib { (tib)->tib_canceled = 0; \ (tib)->tib_dtv = (dtv); \ (tib)->tib_errno = 0; \ + (tib)->tib_thread_flags = 0; \ _TIB_PREP(tib); \ } while (0) diff --git a/sys/dev/pv/if_vio.c b/sys/dev/pv/if_vio.c index 7b8952384..5c9a05faf 100644 --- a/sys/dev/pv/if_vio.c +++ b/sys/dev/pv/if_vio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vio.c,v 1.26 2023/11/10 15:51:24 bluhm Exp $ */ +/* $OpenBSD: if_vio.c,v 1.27 2023/12/09 10:36:05 jan Exp $ */ /* * Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg. @@ -145,6 +145,7 @@ struct virtio_net_hdr { } __packed; #define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 /* flags */ +#define VIRTIO_NET_HDR_F_DATA_VALID 2 /* flags */ #define VIRTIO_NET_HDR_GSO_NONE 0 /* gso_type */ #define VIRTIO_NET_HDR_GSO_TCPV4 1 /* gso_type */ #define VIRTIO_NET_HDR_GSO_UDP 3 /* gso_type */ @@ -533,7 +534,7 @@ vio_attach(struct device *parent, struct device *self, void *aux) vsc->sc_driver_features = VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS | VIRTIO_NET_F_CTRL_VQ | VIRTIO_NET_F_CTRL_RX | VIRTIO_NET_F_MRG_RXBUF | VIRTIO_NET_F_CSUM | - VIRTIO_F_RING_EVENT_IDX; + VIRTIO_F_RING_EVENT_IDX | VIRTIO_NET_F_GUEST_CSUM; virtio_negotiate_features(vsc, virtio_net_feature_names); if (virtio_has_feature(vsc, VIRTIO_NET_F_MAC)) { @@ -986,6 +987,31 @@ vio_populate_rx_mbufs(struct vio_softc *sc) timeout_add_sec(&sc->sc_rxtick, 1); } +void +vio_rx_offload(struct mbuf *m, struct virtio_net_hdr *hdr) +{ + struct ether_extracted ext; + + if (!ISSET(hdr->flags, VIRTIO_NET_HDR_F_DATA_VALID) && + !ISSET(hdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM)) + return; + + ether_extract_headers(m, &ext); + + if (ext.ip4) + SET(m->m_pkthdr.csum_flags, M_IPV4_CSUM_IN_OK); + + if (ext.tcp) { + SET(m->m_pkthdr.csum_flags, M_TCP_CSUM_IN_OK); + if (ISSET(hdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM)) + SET(m->m_pkthdr.csum_flags, M_TCP_CSUM_OUT); + } else if (ext.udp) { + SET(m->m_pkthdr.csum_flags, M_UDP_CSUM_IN_OK); + if (ISSET(hdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM)) + SET(m->m_pkthdr.csum_flags, M_UDP_CSUM_OUT); + } +} + /* dequeue received packets */ int vio_rxeof(struct vio_softc *sc) @@ -1019,6 +1045,8 @@ vio_rxeof(struct vio_softc *sc) bufs_left = hdr->num_buffers - 1; else bufs_left = 0; + if (virtio_has_feature(vsc, VIRTIO_NET_F_GUEST_CSUM)) + vio_rx_offload(m, hdr); } else { m->m_flags &= ~M_PKTHDR; m0->m_pkthdr.len += m->m_len; diff --git a/sys/net/if_pflow.c b/sys/net/if_pflow.c index c1d07be29..67e8282b8 100644 --- a/sys/net/if_pflow.c +++ b/sys/net/if_pflow.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pflow.c,v 1.100 2023/11/09 08:53:20 mvs Exp $ */ +/* $OpenBSD: if_pflow.c,v 1.102 2023/12/08 23:15:44 mvs Exp $ */ /* * Copyright (c) 2011 Florian Obser @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -147,6 +148,7 @@ pflow_clone_create(struct if_clone *ifc, int unit) pflowif = malloc(sizeof(*pflowif), M_DEVBUF, M_WAITOK|M_ZERO); rw_init(&pflowif->sc_lock, "pflowlk"); + mtx_init(&pflowif->sc_mtx, IPL_MPFLOOR); MGET(pflowif->send_nam, M_WAIT, MT_SONAME); pflowif->sc_version = PFLOW_PROTO_DEFAULT; @@ -347,6 +349,8 @@ pflow_set(struct pflow_softc *sc, struct pflowreq *pflowr) } } + rw_assert_wrlock(&sc->sc_lock); + pflow_flush(sc); if (pflowr->addrmask & PFLOW_MASK_DSTIP) { @@ -461,6 +465,8 @@ pflow_set(struct pflow_softc *sc, struct pflowreq *pflowr) sc->so = NULL; } + mtx_enter(&sc->sc_mtx); + /* error check is above */ if (pflowr->addrmask & PFLOW_MASK_VERSION) sc->sc_version = pflowr->version; @@ -479,6 +485,8 @@ pflow_set(struct pflow_softc *sc, struct pflowreq *pflowr) break; } + mtx_leave(&sc->sc_mtx); + return (0); } @@ -504,10 +512,12 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data) NET_LOCK(); if ((ifp->if_flags & IFF_UP) && sc->so != NULL) { ifp->if_flags |= IFF_RUNNING; - sc->sc_gcounter=pflowstats.pflow_flows; + mtx_enter(&sc->sc_mtx); + sc->sc_gcounter = pflowstats.pflow_flows; /* send templates on startup */ if (sc->sc_version == PFLOW_PROTO_10) pflow_sendout_ipfix_tmpl(sc); + mtx_leave(&sc->sc_mtx); } else ifp->if_flags &= ~IFF_RUNNING; rw_exit_read(&sc->sc_lock); @@ -519,19 +529,28 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ifr->ifr_mtu = MCLBYTES; if (ifr->ifr_mtu < ifp->if_mtu) pflow_flush(sc); + mtx_enter(&sc->sc_mtx); pflow_setmtu(sc, ifr->ifr_mtu); + mtx_leave(&sc->sc_mtx); break; case SIOCGETPFLOW: bzero(&pflowr, sizeof(pflowr)); + /* XXXSMP: enforce lock order */ + NET_UNLOCK(); + rw_enter_read(&sc->sc_lock); + NET_LOCK(); if (sc->sc_flowsrc != NULL) memcpy(&pflowr.flowsrc, sc->sc_flowsrc, sc->sc_flowsrc->sa_len); if (sc->sc_flowdst != NULL) memcpy(&pflowr.flowdst, sc->sc_flowdst, sc->sc_flowdst->sa_len); + rw_exit_read(&sc->sc_lock); + mtx_enter(&sc->sc_mtx); pflowr.version = sc->sc_version; + mtx_leave(&sc->sc_mtx); if ((error = copyout(&pflowr, ifr->ifr_data, sizeof(pflowr)))) @@ -557,9 +576,11 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data) if ((ifp->if_flags & IFF_UP) && sc->so != NULL) { ifp->if_flags |= IFF_RUNNING; - sc->sc_gcounter=pflowstats.pflow_flows; + mtx_enter(&sc->sc_mtx); + sc->sc_gcounter = pflowstats.pflow_flows; if (sc->sc_version == PFLOW_PROTO_10) pflow_sendout_ipfix_tmpl(sc); + mtx_leave(&sc->sc_mtx); } else ifp->if_flags &= ~IFF_RUNNING; rw_exit_write(&sc->sc_lock); @@ -575,7 +596,6 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data) int pflow_calc_mtu(struct pflow_softc *sc, int mtu, int hdrsz) { - sc->sc_maxcount4 = (mtu - hdrsz - sizeof(struct udpiphdr)) / sizeof(struct pflow_ipfix_flow4); sc->sc_maxcount6 = (mtu - hdrsz - @@ -622,6 +642,8 @@ pflow_get_mbuf(struct pflow_softc *sc, u_int16_t set_id) struct pflow_header h; struct mbuf *m; + MUTEX_ASSERT_LOCKED(&sc->sc_mtx); + MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) { pflowstats.pflow_onomem++; @@ -791,6 +813,7 @@ export_pflow(struct pf_state *st) sk = st->key[st->direction == PF_IN ? PF_SK_WIRE : PF_SK_STACK]; SLIST_FOREACH(sc, &pflowif_list, sc_next) { + mtx_enter(&sc->sc_mtx); switch (sc->sc_version) { case PFLOW_PROTO_5: if( sk->af == AF_INET ) @@ -803,6 +826,7 @@ export_pflow(struct pf_state *st) default: /* NOTREACHED */ break; } + mtx_leave(&sc->sc_mtx); } return (0); @@ -864,6 +888,8 @@ copy_flow_to_m(struct pflow_flow *flow, struct pflow_softc *sc) { int ret = 0; + MUTEX_ASSERT_LOCKED(&sc->sc_mtx); + if (sc->sc_mbuf == NULL) { if ((sc->sc_mbuf = pflow_get_mbuf(sc, 0)) == NULL) return (ENOBUFS); @@ -888,6 +914,8 @@ copy_flow_ipfix_4_to_m(struct pflow_ipfix_flow4 *flow, struct pflow_softc *sc) { int ret = 0; + MUTEX_ASSERT_LOCKED(&sc->sc_mtx); + if (sc->sc_mbuf == NULL) { if ((sc->sc_mbuf = pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV4_ID)) == NULL) { @@ -915,6 +943,8 @@ copy_flow_ipfix_6_to_m(struct pflow_ipfix_flow6 *flow, struct pflow_softc *sc) { int ret = 0; + MUTEX_ASSERT_LOCKED(&sc->sc_mtx); + if (sc->sc_mbuf6 == NULL) { if ((sc->sc_mbuf6 = pflow_get_mbuf(sc, PFLOW_IPFIX_TMPL_IPV6_ID)) == NULL) { @@ -1011,6 +1041,7 @@ pflow_timeout(void *v) { struct pflow_softc *sc = v; + mtx_enter(&sc->sc_mtx); switch (sc->sc_version) { case PFLOW_PROTO_5: pflow_sendout_v5(sc); @@ -1021,6 +1052,7 @@ pflow_timeout(void *v) default: /* NOTREACHED */ break; } + mtx_leave(&sc->sc_mtx); } void @@ -1028,7 +1060,9 @@ pflow_timeout6(void *v) { struct pflow_softc *sc = v; + mtx_enter(&sc->sc_mtx); pflow_sendout_ipfix(sc, AF_INET6); + mtx_leave(&sc->sc_mtx); } void @@ -1036,12 +1070,15 @@ pflow_timeout_tmpl(void *v) { struct pflow_softc *sc = v; + mtx_enter(&sc->sc_mtx); pflow_sendout_ipfix_tmpl(sc); + mtx_leave(&sc->sc_mtx); } void pflow_flush(struct pflow_softc *sc) { + mtx_enter(&sc->sc_mtx); switch (sc->sc_version) { case PFLOW_PROTO_5: pflow_sendout_v5(sc); @@ -1053,6 +1090,7 @@ pflow_flush(struct pflow_softc *sc) default: /* NOTREACHED */ break; } + mtx_leave(&sc->sc_mtx); } int @@ -1063,6 +1101,8 @@ pflow_sendout_v5(struct pflow_softc *sc) struct ifnet *ifp = &sc->sc_if; struct timespec tv; + MUTEX_ASSERT_LOCKED(&sc->sc_mtx); + timeout_del(&sc->sc_tmo); if (m == NULL) @@ -1099,6 +1139,8 @@ pflow_sendout_ipfix(struct pflow_softc *sc, sa_family_t af) u_int32_t count; int set_length; + MUTEX_ASSERT_LOCKED(&sc->sc_mtx); + switch (af) { case AF_INET: m = sc->sc_mbuf; @@ -1158,12 +1200,14 @@ pflow_sendout_ipfix_tmpl(struct pflow_softc *sc) struct pflow_v10_header *h10; struct ifnet *ifp = &sc->sc_if; + MUTEX_ASSERT_LOCKED(&sc->sc_mtx); + timeout_del(&sc->sc_tmo_tmpl); if (!(ifp->if_flags & IFF_RUNNING)) { return (0); } - m = pflow_get_mbuf(NULL, 0); + m = pflow_get_mbuf(sc, 0); if (m == NULL) return (0); if (m_copyback(m, 0, sizeof(struct pflow_ipfix_tmpl), @@ -1196,6 +1240,8 @@ pflow_sendout_ipfix_tmpl(struct pflow_softc *sc) int pflow_sendout_mbuf(struct pflow_softc *sc, struct mbuf *m) { + rw_assert_anylock(&sc->sc_lock); + counters_pkt(sc->sc_if.if_counters, ifc_opackets, ifc_obytes, m->m_pkthdr.len); diff --git a/sys/net/if_pflow.h b/sys/net/if_pflow.h index 9d7577074..430ddb3c0 100644 --- a/sys/net/if_pflow.h +++ b/sys/net/if_pflow.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pflow.h,v 1.19 2022/11/23 15:12:27 mvs Exp $ */ +/* $OpenBSD: if_pflow.h,v 1.20 2023/12/08 23:13:40 mvs Exp $ */ /* * Copyright (c) 2008 Henning Brauer @@ -171,37 +171,42 @@ struct pflow_ipfix_flow6 { /* * Locks used to protect struct members and global data + * I immutable after creation * N net lock + * m this pflow_softc' `sc_mtx' * p this pflow_softc' `sc_lock' */ struct pflow_softc { + struct mutex sc_mtx; struct rwlock sc_lock; int sc_dying; /* [N] */ struct ifnet sc_if; - unsigned int sc_count; - unsigned int sc_count4; - unsigned int sc_count6; - unsigned int sc_maxcount; - unsigned int sc_maxcount4; - unsigned int sc_maxcount6; - u_int64_t sc_gcounter; - u_int32_t sc_sequence; + unsigned int sc_count; /* [m] */ + unsigned int sc_count4; /* [m] */ + unsigned int sc_count6; /* [m] */ + unsigned int sc_maxcount; /* [m] */ + unsigned int sc_maxcount4; /* [m] */ + unsigned int sc_maxcount6; /* [m] */ + u_int64_t sc_gcounter; /* [m] */ + u_int32_t sc_sequence; /* [m] */ struct timeout sc_tmo; struct timeout sc_tmo6; struct timeout sc_tmo_tmpl; struct mbuf_queue sc_outputqueue; struct task sc_outputtask; struct socket *so; /* [p] */ - struct mbuf *send_nam; - struct sockaddr *sc_flowsrc; - struct sockaddr *sc_flowdst; - struct pflow_ipfix_tmpl sc_tmpl_ipfix; - u_int8_t sc_version; - struct mbuf *sc_mbuf; /* current cumulative mbuf */ - struct mbuf *sc_mbuf6; /* current cumulative mbuf */ + struct mbuf *send_nam; /* [p] */ + struct sockaddr *sc_flowsrc; /* [p] */ + struct sockaddr *sc_flowdst; /* [p] */ + struct pflow_ipfix_tmpl sc_tmpl_ipfix; /* [I] */ + u_int8_t sc_version; /* [m] */ + struct mbuf *sc_mbuf; /* [m] current cumulative + mbuf */ + struct mbuf *sc_mbuf6; /* [m] current cumulative + mbuf */ SLIST_ENTRY(pflow_softc) sc_next; }; diff --git a/usr.sbin/rpki-client/parser.c b/usr.sbin/rpki-client/parser.c index 8e4abdc1d..61a66db01 100644 --- a/usr.sbin/rpki-client/parser.c +++ b/usr.sbin/rpki-client/parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.c,v 1.100 2023/10/13 12:06:49 job Exp $ */ +/* $OpenBSD: parser.c,v 1.101 2023/12/09 00:44:18 job Exp $ */ /* * Copyright (c) 2019 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -310,7 +310,7 @@ proc_parser_mft_pre(struct entity *entp, enum location loc, char **file, */ static struct mft * proc_parser_mft_post(char *file, struct mft *mft, const char *path, - const char *errstr) + const char *errstr, int *warned) { /* check that now is not before from */ time_t now = get_current_time(); @@ -318,6 +318,8 @@ proc_parser_mft_post(char *file, struct mft *mft, const char *path, if (mft == NULL) { if (errstr == NULL) errstr = "no valid mft available"; + if ((*warned)++ > 0) + return NULL; warnx("%s: %s", file, errstr); return NULL; } @@ -359,13 +361,14 @@ proc_parser_mft(struct entity *entp, struct mft **mp, char **crlfile, struct crl *crl, *crl1, *crl2; char *file, *file1, *file2, *crl1file, *crl2file; const char *err1, *err2; + int warned = 0; *mp = NULL; *crlmtime = 0; - mft1 = proc_parser_mft_pre(entp, DIR_VALID, &file1, &crl1, &crl1file, + mft1 = proc_parser_mft_pre(entp, DIR_TEMP, &file1, &crl1, &crl1file, &err1); - mft2 = proc_parser_mft_pre(entp, DIR_TEMP, &file2, &crl2, &crl2file, + mft2 = proc_parser_mft_pre(entp, DIR_VALID, &file2, &crl2, &crl2file, &err2); /* overload error from temp file if it is set */ @@ -374,20 +377,36 @@ proc_parser_mft(struct entity *entp, struct mft **mp, char **crlfile, err1 = err2; if (mft_compare(mft1, mft2) == 1) { + *mp = proc_parser_mft_post(file1, mft1, entp->path, err1, + &warned); + if (*mp == NULL) { + mft1 = NULL; + if (mft2 != NULL) + warnx("%s: failed fetch, continuing with #%s", + file2, mft2->seqnum); + } + } + + if (*mp != NULL) { mft_free(mft2); crl_free(crl2); free(crl2file); free(file2); - *mp = proc_parser_mft_post(file1, mft1, entp->path, err1); + crl = crl1; file = file1; *crlfile = crl1file; } else { + if (err2 == NULL) + err2 = err1; + *mp = proc_parser_mft_post(file2, mft2, entp->path, err2, + &warned); + mft_free(mft1); crl_free(crl1); free(crl1file); free(file1); - *mp = proc_parser_mft_post(file2, mft2, entp->path, err2); + crl = crl2; file = file2; *crlfile = crl2file;