aboutsummaryrefslogtreecommitdiffstats
path: root/src/if_wg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/if_wg.c')
-rw-r--r--src/if_wg.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/src/if_wg.c b/src/if_wg.c
index a69d2ee..0d22adf 100644
--- a/src/if_wg.c
+++ b/src/if_wg.c
@@ -130,8 +130,8 @@ struct wg_tag *wg_mbuf_get_tag(struct mbuf *);
void wg_route_init(struct wg_route *);
void wg_route_broken(struct wg_route *);
-void wg_route_queue(struct wg_route *, enum wg_pkt_type);
-void wg_peer_queue(struct wg_peer *, enum wg_pkt_type);
+void wg_route_queue(struct wg_route *, enum wg_pkt_type, uint32_t);
+void wg_peer_queue(struct wg_peer *, enum wg_pkt_type, uint32_t);
void wg_encrypt_hs(struct mbuf *);
void wg_encrypt(struct mbuf *);
@@ -381,7 +381,7 @@ wg_mbuf_get_tag(struct mbuf *m)
void
wg_route_send_initiation(struct wg_route *r)
{
- wg_route_queue(r, WG_PKT_INITIATION);
+ wg_route_queue(r, WG_PKT_INITIATION, r->r_peer->p_id);
}
void
@@ -389,13 +389,19 @@ wg_route_broken(struct wg_route *r)
{
DPRINTF(r->r_sc, "broken session %x\n", r->r_peer->p_id);
wg_peer_clean(r->r_peer);
- wg_route_queue(r, WG_PKT_INITIATION);
+ wg_route_queue(r, WG_PKT_INITIATION, r->r_peer->p_id);
}
void
wg_route_send_keepalive(struct wg_route *r)
{
- wg_route_queue(r, WG_PKT_TRANSPORT);
+ struct wg_session *session;
+ if ((session = wg_peer_ks_session(r->r_peer)) == NULL) {
+ wg_route_send_initiation(r);
+ } else {
+ wg_route_queue(r, WG_PKT_TRANSPORT, session->s_local_id);
+ wg_session_put(session);
+ }
}
void
@@ -406,7 +412,7 @@ wg_route_clean(struct wg_route *r)
}
void
-wg_route_queue(struct wg_route *route, enum wg_pkt_type type)
+wg_route_queue(struct wg_route *route, enum wg_pkt_type type, uint32_t dst)
{
struct mbuf *m;
struct wg_tag *tag;
@@ -416,7 +422,7 @@ wg_route_queue(struct wg_route *route, enum wg_pkt_type type)
tag = wg_mbuf_get_tag(m);
tag->t_sc = sc;
- tag->t_dst = route->r_peer->p_id;
+ tag->t_dst = dst;
tag->t_type = type;
tag->t_state = WG_PKT_STATE_NEW;
@@ -424,7 +430,6 @@ wg_route_queue(struct wg_route *route, enum wg_pkt_type type)
m_calchdrlen(m);
if (type == WG_PKT_TRANSPORT) {
- /* TODO calculate length better */
m->m_len = 0;
m_calchdrlen(m);
mpq_enqueue(&sc->sc_tx_queue, m);
@@ -436,9 +441,9 @@ wg_route_queue(struct wg_route *route, enum wg_pkt_type type)
}
void
-wg_peer_queue(struct wg_peer *peer, enum wg_pkt_type type)
+wg_peer_queue(struct wg_peer *peer, enum wg_pkt_type type, uint32_t dst)
{
- wg_route_queue(peer->p_arg, type);
+ wg_route_queue(peer->p_arg, type, dst);
}
void
@@ -470,7 +475,7 @@ wg_encrypt_hs(struct mbuf *m)
panic("invalid packet type: %d\n", tag->t_type);
}
- DPRINTF(tag->t_sc, "%s tx for %x, id %x\n", wg_pkt_str[tag->t_type],
+ DPRINTF(tag->t_sc, "tx %s for %x, id %x\n", wg_pkt_str[tag->t_type],
session->s_peer->p_id, session->s_local_id);
m->m_pkthdr.ph_cookie = m;
@@ -479,7 +484,7 @@ wg_encrypt_hs(struct mbuf *m)
wg_session_put(session);
return;
drop:
- DPRINTF(tag->t_sc, "failed %s tx: %s\n", wg_pkt_str[tag->t_type],
+ DPRINTF(tag->t_sc, "%s tx failed: %s\n", wg_pkt_str[tag->t_type],
wg_error_str[err]);
tag->t_state = WG_PKT_STATE_DEAD;
}
@@ -583,7 +588,7 @@ wg_decrypt_hs(struct mbuf *m)
panic("not a handshake packet: %d", tag->t_type);
}
- DPRINTF(tag->t_sc, "%s rx for %x, id %x\n", wg_pkt_str[tag->t_type],
+ DPRINTF(tag->t_sc, "rx %s for %x, id %x\n", wg_pkt_str[tag->t_type],
session->s_peer->p_id, session->s_local_id);
tag->t_state = WG_PKT_STATE_DONE;
@@ -592,7 +597,7 @@ wg_decrypt_hs(struct mbuf *m)
return;
drop:
counters_inc(tag->t_sc->sc_if.if_counters, ifc_ierrors);
- DPRINTF(tag->t_sc, "failed %s rx: %s\n", wg_pkt_str[tag->t_type], wg_error_str[err]);
+ DPRINTF(tag->t_sc, "%s rx failed: %s\n", wg_pkt_str[tag->t_type], wg_error_str[err]);
tag->t_state = WG_PKT_STATE_DEAD;
}
@@ -681,6 +686,7 @@ wg_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
int error;
struct wg_tag *tag;
struct wg_route *route;
+ struct wg_session *session;
struct wg_softc *sc = ifp->if_softc;
if (!AF_VAL(sa->sa_family, 1, 1)) {
@@ -719,18 +725,19 @@ wg_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
BPF_DIRECTION_IN);
#endif
- tag->t_sc = sc;
- tag->t_dst = route->r_peer->p_id;
- tag->t_type = WG_PKT_TRANSPORT;
- tag->t_state = WG_PKT_STATE_NEW;
-
- if (wg_peer_has_transport_session(route->r_peer) != WG_OK) {
+ if ((session = wg_peer_ks_session(route->r_peer)) == NULL) {
if (mq_push(&route->r_outgoing, m) != 0)
counters_inc(sc->sc_if.if_counters, ifc_oqdrops);
wg_route_send_initiation(route);
return 0;
}
+ tag->t_sc = sc;
+ tag->t_dst = session->s_local_id;
+ tag->t_type = WG_PKT_TRANSPORT;
+ tag->t_state = WG_PKT_STATE_NEW;
+ wg_session_put(session);
+
if ((error = if_enqueue(ifp, m)) != 0) {
counters_inc(sc->sc_if.if_counters, ifc_oqdrops);
if_start(ifp);
@@ -1162,6 +1169,7 @@ wg_ioctl_get_serv(struct wg_softc *sc, struct wg_get_serv *wgs)
struct map_item *item;
struct wg_peer *peer;
+ /* For the time being, no lock as we hold kernel lock in ioctl */
FM_FOREACH_FILLED(item, &sc->sc_dev.d_peers) {
if (num < wgs->gs_num_peers) {
peer = item->value;