summaryrefslogtreecommitdiff
path: root/sys/net/if_bridge.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/if_bridge.c')
-rw-r--r--sys/net/if_bridge.c70
1 files changed, 37 insertions, 33 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 80c4b7e67ec..1b01b47c295 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.283 2016/09/02 10:01:36 goda Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.284 2016/09/03 13:46:57 reyk Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -715,6 +715,7 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
struct bridge_rtnode *dst_p = NULL;
struct ether_addr *dst;
struct bridge_softc *sc;
+ struct bridge_tunneltag *brtag;
int error;
/* ifp must be a member interface of the bridge. */
@@ -811,9 +812,15 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
}
sendunicast:
- if (dst_p != NULL && dst_p->brt_tunnel.sa.sa_family != AF_UNSPEC &&
- (sa = bridge_tunneltag(m, dst_p->brt_tunnel.sa.sa_family)) != NULL)
- memcpy(sa, &dst_p->brt_tunnel.sa, dst_p->brt_tunnel.sa.sa_len);
+ if ((dst_p != NULL) &&
+ (dst_p->brt_tunnel.brtag_dst.sa.sa_family != AF_UNSPEC) &&
+ ((brtag = bridge_tunneltag(m)) != NULL)) {
+ memcpy(&brtag->brtag_src, &dst_p->brt_tunnel.brtag_src.sa,
+ dst_p->brt_tunnel.brtag_src.sa.sa_len);
+ memcpy(&brtag->brtag_dst, &dst_p->brt_tunnel.brtag_dst.sa,
+ dst_p->brt_tunnel.brtag_dst.sa.sa_len);
+ brtag->brtag_id = dst_p->brt_tunnel.brtag_id;
+ }
bridge_span(sc, m);
if ((dst_if->if_flags & IFF_RUNNING) == 0) {
@@ -1942,7 +1949,7 @@ bridge_send_icmp_err(struct bridge_softc *sc, struct ifnet *ifp,
m_freem(n);
}
-struct sockaddr *
+struct bridge_tunneltag *
bridge_tunnel(struct mbuf *m)
{
struct m_tag *mtag;
@@ -1950,41 +1957,24 @@ bridge_tunnel(struct mbuf *m)
if ((mtag = m_tag_find(m, PACKET_TAG_TUNNEL, NULL)) == NULL)
return (NULL);
- return ((struct sockaddr *)(mtag + 1));
+ return ((struct bridge_tunneltag *)(mtag + 1));
}
-struct sockaddr *
-bridge_tunneltag(struct mbuf *m, int af)
+struct bridge_tunneltag *
+bridge_tunneltag(struct mbuf *m)
{
- struct m_tag *mtag;
- size_t len;
- struct sockaddr *sa;
-
- if ((mtag = m_tag_find(m, PACKET_TAG_TUNNEL, NULL)) != NULL) {
- sa = (struct sockaddr *)(mtag + 1);
- if (sa->sa_family != af) {
- m_tag_delete(m, mtag);
- mtag = NULL;
- }
- }
- if (mtag == NULL) {
- if (af == AF_INET)
- len = sizeof(struct sockaddr_in);
- else if (af == AF_INET6)
- len = sizeof(struct sockaddr_in6);
- else
- return (NULL);
- mtag = m_tag_get(PACKET_TAG_TUNNEL, len, M_NOWAIT);
+ struct m_tag *mtag;
+
+ if ((mtag = m_tag_find(m, PACKET_TAG_TUNNEL, NULL)) == NULL) {
+ mtag = m_tag_get(PACKET_TAG_TUNNEL,
+ sizeof(struct bridge_tunneltag), M_NOWAIT);
if (mtag == NULL)
return (NULL);
- bzero(mtag + 1, len);
- sa = (struct sockaddr *)(mtag + 1);
- sa->sa_family = af;
- sa->sa_len = len;
+ bzero(mtag + 1, sizeof(struct bridge_tunneltag));
m_tag_prepend(m, mtag);
}
- return ((struct sockaddr *)(mtag + 1));
+ return ((struct bridge_tunneltag *)(mtag + 1));
}
void
@@ -2000,6 +1990,20 @@ bridge_copyaddr(struct sockaddr *src, struct sockaddr *dst)
{
if (src != NULL && src->sa_family != AF_UNSPEC)
memcpy(dst, src, src->sa_len);
- else
+ else {
dst->sa_family = AF_UNSPEC;
+ dst->sa_len = 0;
+ }
+}
+
+void
+bridge_copytag(struct bridge_tunneltag *src, struct bridge_tunneltag *dst)
+{
+ if (src == NULL) {
+ memset(dst, 0, sizeof(*dst));
+ } else {
+ bridge_copyaddr(&src->brtag_src.sa, &dst->brtag_src.sa);
+ bridge_copyaddr(&src->brtag_dst.sa, &dst->brtag_dst.sa);
+ dst->brtag_id = src->brtag_id;
+ }
}