Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/if_wg/module/if_wg_session.c
Show First 20 Lines • Show All 1,899 Lines • ▼ Show 20 Lines | wg_input(struct mbuf *m0, int offset, struct inpcb *inpcb, | ||||
struct wg_tag *t; | struct wg_tag *t; | ||||
void *data; | void *data; | ||||
uh = (struct udphdr *)(m0->m_data + offset); | uh = (struct udphdr *)(m0->m_data + offset); | ||||
hlen = offset + sizeof(struct udphdr); | hlen = offset + sizeof(struct udphdr); | ||||
m_adj(m0, hlen); | m_adj(m0, hlen); | ||||
/* | /* | ||||
* Ensure mbuf is contiguous over full length of the packet. This is | * Ensure mbuf is contiguous over full length of the packet. This is | ||||
* done so that we can directly read the handshake values in | * done so that we can directly read the handshake values in | ||||
* wg_handshake, and so we can decrypt a transport packet by passing a | * wg_handshake, and so we can decrypt a transport packet by passing a | ||||
* a single buffer to noise_remote_decrypt() in wg_decap. | * a single buffer to noise_remote_decrypt() in wg_decap. | ||||
*/ | */ | ||||
if ((m = m_pullup(m0, m0->m_pkthdr.len)) == NULL) { | if ((m = m_pullup(m0, m0->m_pkthdr.len)) == NULL) { | ||||
afedorov: Hmm, is m_defrag() really needed here? This is a very costly operation due to allocation. | |||||
Done Inline ActionsThat's a good question. wg_handshake() assumes that the entire packet is contiguous, though, so a pullup to get the packet type is not sufficient. markj: That's a good question. wg_handshake() assumes that the entire packet is contiguous, though, so… | |||||
DPRINTF(sc, "DEFRAG fail\n"); | DPRINTF(sc, "DEFRAG fail\n"); | ||||
m_freem(m0); | |||||
return; | return; | ||||
} | } | ||||
data = mtod(m, void *); | data = mtod(m, void *); | ||||
pkttype = le32toh(*(uint32_t*)data); | pkttype = le32toh(*(uint32_t*)data); | ||||
t = wg_tag_get(m); | t = wg_tag_get(m); | ||||
if (t == NULL) { | if (t == NULL) { | ||||
DPRINTF(sc, "no tag\n"); | DPRINTF(sc, "no tag\n"); | ||||
goto free; | goto free; | ||||
Show All 12 Lines | wg_input(struct mbuf *m0, int offset, struct inpcb *inpcb, | ||||
if ((pktlen == sizeof(struct wg_pkt_initiation) && | if ((pktlen == sizeof(struct wg_pkt_initiation) && | ||||
pkttype == MESSAGE_HANDSHAKE_INITIATION) || | pkttype == MESSAGE_HANDSHAKE_INITIATION) || | ||||
(pktlen == sizeof(struct wg_pkt_response) && | (pktlen == sizeof(struct wg_pkt_response) && | ||||
pkttype == MESSAGE_HANDSHAKE_RESPONSE) || | pkttype == MESSAGE_HANDSHAKE_RESPONSE) || | ||||
(pktlen == sizeof(struct wg_pkt_cookie) && | (pktlen == sizeof(struct wg_pkt_cookie) && | ||||
pkttype == MESSAGE_HANDSHAKE_COOKIE)) { | pkttype == MESSAGE_HANDSHAKE_COOKIE)) { | ||||
verify_endpoint(m); | verify_endpoint(m); | ||||
if (mbufq_enqueue(&sc->sc_handshake_queue, m) == 0) { | if (mbufq_enqueue(&sc->sc_handshake_queue, m) == 0) { | ||||
Done Inline ActionsHow is this queue locked? markj: How is this queue locked? | |||||
GROUPTASK_ENQUEUE(&sc->sc_handshake); | GROUPTASK_ENQUEUE(&sc->sc_handshake); | ||||
} else | } else { | ||||
DPRINTF(sc, "Dropping handshake packet\n"); | DPRINTF(sc, "Dropping handshake packet\n"); | ||||
wg_m_freem(m); | |||||
} | |||||
} else if (pktlen >= sizeof(struct wg_pkt_data) + NOISE_MAC_SIZE | } else if (pktlen >= sizeof(struct wg_pkt_data) + NOISE_MAC_SIZE | ||||
&& pkttype == MESSAGE_DATA) { | && pkttype == MESSAGE_DATA) { | ||||
pkt_data = data; | pkt_data = data; | ||||
remote = wg_index_get(sc, pkt_data->data.r_idx); | remote = wg_index_get(sc, pkt_data->data.r_idx); | ||||
if (remote == NULL) { | if (remote == NULL) { | ||||
DPRINTF(sc, "no remote\n"); | DPRINTF(sc, "no remote\n"); | ||||
if_inc_counter(sc->sc_ifp, IFCOUNTER_IERRORS, 1); | if_inc_counter(sc->sc_ifp, IFCOUNTER_IERRORS, 1); | ||||
Show All 33 Lines |
Hmm, is m_defrag() really needed here? This is a very costly operation due to allocation. Because we only need to get "pkttype", maybe using m_pullup is enough?