aboutsummaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorQing Li <qingli@FreeBSD.org>2010-03-12 10:24:58 +0000
committerQing Li <qingli@FreeBSD.org>2010-03-12 10:24:58 +0000
commit688ba6823b7e5dfe724c8548caa0b6f4a3e918ba (patch)
treef8af5a5b05d495c78b205108edcfde0f42dba818 /sys/net
parent63d46d1d5e917088f08cafa7f9b328073417d7e7 (diff)
downloadsrc-688ba6823b7e5dfe724c8548caa0b6f4a3e918ba.tar.gz
src-688ba6823b7e5dfe724c8548caa0b6f4a3e918ba.zip
The flow-table module retrieves the destination and source
address as well as the transport protocol port information from the outbound packets. The routing code is generic and compares every byte in the given sockaddr object. Therefore the temporary sockaddr objects must be cleared due to padding bytes. In addition, the port information must be stripped or the route search will either fail or return the incorrect route entry. Unit testing is done using OpenVPN over the if_tun interface. MFC after: 7 days
Notes
Notes: svn path=/head/; revision=205077
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/flowtable.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c
index e010f6ae1e8d..13cf8d26d9ce 100644
--- a/sys/net/flowtable.c
+++ b/sys/net/flowtable.c
@@ -593,6 +593,8 @@ flowtable_lookup_mbuf4(struct flowtable *ft, struct mbuf *m)
dsin = (struct sockaddr_in *)&dsa;
ssin = (struct sockaddr_in *)&ssa;
+ bzero(dsin, sizeof(*dsin));
+ bzero(ssin, sizeof(*ssin));
flags = ft->ft_flags;
if (ipv4_mbuf_demarshal(ft, m, ssin, dsin, &flags) != 0)
return (NULL);
@@ -796,6 +798,8 @@ flowtable_lookup_mbuf6(struct flowtable *ft, struct mbuf *m)
dsin6 = (struct sockaddr_in6 *)&dsa;
ssin6 = (struct sockaddr_in6 *)&ssa;
+ bzero(dsin6, sizeof(*dsin6));
+ bzero(ssin6, sizeof(*ssin6));
flags = ft->ft_flags;
if (ipv6_mbuf_demarshal(ft, m, ssin6, dsin6, &flags) != 0)
@@ -1088,6 +1092,14 @@ flowtable_lookup(struct flowtable *ft, struct sockaddr_storage *ssa,
ro = &sro;
memcpy(&ro->ro_dst, dsa, sizeof(struct sockaddr_in));
+ /*
+ * The harvested source and destination addresses
+ * may contain port information if the packet is
+ * from a transport protocol (e.g. TCP/UDP). The
+ * port field must be cleared before performing
+ * a route lookup.
+ */
+ ((struct sockaddr_in *)&ro->ro_dst)->sin_port = 0;
dsin = (struct sockaddr_in *)dsa;
ssin = (struct sockaddr_in *)ssa;
if ((dsin->sin_addr.s_addr == ssin->sin_addr.s_addr) ||
@@ -1105,6 +1117,7 @@ flowtable_lookup(struct flowtable *ft, struct sockaddr_storage *ssa,
ro = (struct route *)&sro6;
memcpy(&sro6.ro_dst, dsa,
sizeof(struct sockaddr_in6));
+ ((struct sockaddr_in6 *)&ro->ro_dst)->sin6_port = 0;
dsin6 = (struct sockaddr_in6 *)dsa;
ssin6 = (struct sockaddr_in6 *)ssa;