summaryrefslogtreecommitdiffstats
path: root/usr.sbin/switchd
diff options
context:
space:
mode:
authorakoshibe <akoshibe@openbsd.org>2019-05-05 21:33:00 +0000
committerakoshibe <akoshibe@openbsd.org>2019-05-05 21:33:00 +0000
commitf03c03ede761419687808c462ec710cb76da397a (patch)
tree2e1755b29ff91401ccbf15fca8e2f2d0194733a7 /usr.sbin/switchd
parentGetting too tight. Surrender a little (diff)
downloadwireguard-openbsd-f03c03ede761419687808c462ec710cb76da397a.tar.xz
wireguard-openbsd-f03c03ede761419687808c462ec710cb76da397a.zip
switchd(8) will sometimes not save a copy of a packet needing forwarding
even when a switch(4) instance requires it to supply it. Cases where this can happen are: if the copy of the packet recieved from the switch is too short (source/destination pairs can't be recovered), is non-unicast, or when switchd has to fall back to flooding traffic. Factor out the check for short packets, stopping before forwarding decisions are made if the full packet is needed by the switch. Set the packet buffer early for cases where it is needed otherwise. Also replace a few bzero's with memset's. Diff based on one by guenther@ OK phessler@
Diffstat (limited to 'usr.sbin/switchd')
-rw-r--r--usr.sbin/switchd/ofp10.c13
-rw-r--r--usr.sbin/switchd/ofp13.c10
-rw-r--r--usr.sbin/switchd/packet.c29
-rw-r--r--usr.sbin/switchd/switchd.h6
4 files changed, 38 insertions, 20 deletions
diff --git a/usr.sbin/switchd/ofp10.c b/usr.sbin/switchd/ofp10.c
index 14a14267c48..e1dbc724c10 100644
--- a/usr.sbin/switchd/ofp10.c
+++ b/usr.sbin/switchd/ofp10.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ofp10.c,v 1.20 2018/09/09 14:21:32 akoshibe Exp $ */
+/* $OpenBSD: ofp10.c,v 1.21 2019/05/05 21:33:00 akoshibe Exp $ */
/*
* Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
@@ -342,7 +342,7 @@ ofp10_packet_match(struct packet *pkt, struct ofp10_match *m, uint32_t flags)
{
struct ether_header *eh = pkt->pkt_eh;
- bzero(m, sizeof(*m));
+ memset(m, 0, sizeof(*m));
m->m_wildcards = htonl(~flags);
if ((flags & (OFP10_WILDCARD_DL_SRC|OFP10_WILDCARD_DL_DST)) &&
@@ -377,12 +377,17 @@ ofp10_packet_in(struct switchd *sc, struct switch_connection *con,
if ((pin = ibuf_getdata(ibuf, sizeof(*pin))) == NULL)
return (-1);
- bzero(&pkt, sizeof(pkt));
+ memset(&pkt, 0, sizeof(pkt));
len = ntohs(pin->pin_total_len);
+
srcport = ntohs(pin->pin_port);
+ if (packet_ether_input(ibuf, len, &pkt) == -1 &&
+ pin->pin_buffer_id == htonl(OFP_PKTOUT_NO_BUFFER))
+ return(-1);
+
if (packet_input(sc, con->con_switch,
- srcport, &dstport, ibuf, len, &pkt) == -1 ||
+ srcport, &dstport, &pkt) == -1 ||
(dstport > OFP10_PORT_MAX &&
dstport != OFP10_PORT_LOCAL &&
dstport != OFP10_PORT_CONTROLLER)) {
diff --git a/usr.sbin/switchd/ofp13.c b/usr.sbin/switchd/ofp13.c
index 0c40a7dbb83..0f6158dfd13 100644
--- a/usr.sbin/switchd/ofp13.c
+++ b/usr.sbin/switchd/ofp13.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ofp13.c,v 1.44 2018/09/09 14:21:32 akoshibe Exp $ */
+/* $OpenBSD: ofp13.c,v 1.45 2019/05/05 21:33:00 akoshibe Exp $ */
/*
* Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
@@ -1029,7 +1029,7 @@ ofp13_packet_in(struct switchd *sc, struct switch_connection *con,
if (pin->pin_reason != OFP_PKTIN_REASON_NO_MATCH)
return (-1);
- bzero(&pkt, sizeof(pkt));
+ memset(&pkt, 0, sizeof(pkt));
len = ntohs(pin->pin_total_len);
/* very basic way of getting the source port */
@@ -1070,8 +1070,12 @@ ofp13_packet_in(struct switchd *sc, struct switch_connection *con,
if (ibuf_getdata(ibuf, off) == NULL)
return (-1);
+ if (packet_ether_input(ibuf, len, &pkt) == -1 &&
+ pin->pin_buffer_id == htonl(OFP_PKTOUT_NO_BUFFER))
+ return(-1);
+
if (packet_input(sc, con->con_switch,
- srcport, &dstport, ibuf, len, &pkt) == -1 ||
+ srcport, &dstport, &pkt) == -1 ||
(dstport > OFP_PORT_MAX &&
dstport != OFP_PORT_LOCAL &&
dstport != OFP_PORT_CONTROLLER)) {
diff --git a/usr.sbin/switchd/packet.c b/usr.sbin/switchd/packet.c
index 01f1011f363..ce93d6f23a8 100644
--- a/usr.sbin/switchd/packet.c
+++ b/usr.sbin/switchd/packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.5 2017/08/06 17:31:19 rob Exp $ */
+/* $OpenBSD: packet.c,v 1.6 2019/05/05 21:33:00 akoshibe Exp $ */
/*
* Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
@@ -50,14 +50,10 @@ packet_ether_unicast(uint8_t *ea)
}
int
-packet_input(struct switchd *sc, struct switch_control *sw, uint32_t srcport,
- uint32_t *dstport, struct ibuf *ibuf, size_t len, struct packet *pkt)
+packet_ether_input(struct ibuf *ibuf, size_t len, struct packet *pkt)
{
struct ether_header *eh;
- struct macaddr *src, *dst;
- if (sw == NULL)
- return (-1);
if (len < sizeof(*eh))
return (-1);
@@ -66,8 +62,24 @@ packet_input(struct switchd *sc, struct switch_control *sw, uint32_t srcport,
log_debug("short packet");
return (-1);
}
- len -= sizeof(*eh);
+ pkt->pkt_eh = eh;
+ pkt->pkt_buf = (uint8_t *)eh;
+
+ return (0);
+}
+
+int
+packet_input(struct switchd *sc, struct switch_control *sw, uint32_t srcport,
+ uint32_t *dstport, struct packet *pkt)
+{
+ struct ether_header *eh;
+ struct macaddr *src, *dst;
+
+ if (sw == NULL)
+ return (-1);
+
+ eh = pkt->pkt_eh;
if ((packet_ether_unicast(eh->ether_shost) == -1) ||
(src = switch_learn(sc, sw, eh->ether_shost, srcport)) == NULL)
return (-1);
@@ -86,8 +98,5 @@ packet_input(struct switchd *sc, struct switch_control *sw, uint32_t srcport,
if (dstport)
*dstport = dst == NULL ? OFP_PORT_ANY : dst->mac_port;
- pkt->pkt_eh = eh;
- pkt->pkt_buf = (uint8_t *)eh;
-
return (0);
}
diff --git a/usr.sbin/switchd/switchd.h b/usr.sbin/switchd/switchd.h
index 68549f7c2b9..01faff7c386 100644
--- a/usr.sbin/switchd/switchd.h
+++ b/usr.sbin/switchd/switchd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: switchd.h,v 1.28 2016/12/22 15:31:43 rzalamena Exp $ */
+/* $OpenBSD: switchd.h,v 1.29 2019/05/05 21:33:00 akoshibe Exp $ */
/*
* Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
@@ -211,9 +211,9 @@ struct switch_connection *
switchd_connbyaddr(struct switchd *, struct sockaddr *);
/* packet.c */
+int packet_ether_input(struct ibuf *, size_t, struct packet *);
int packet_input(struct switchd *, struct switch_control *,
- uint32_t, uint32_t *, struct ibuf *, size_t,
- struct packet *);
+ uint32_t, uint32_t *, struct packet *);
/* switch.c */
void switch_init(struct switchd *);