svn commit: r286013 - in head/sys: net netinet netinet6

Andrey V. Elsukov ae at FreeBSD.org
Wed Jul 29 14:07:45 UTC 2015


Author: ae
Date: Wed Jul 29 14:07:43 2015
New Revision: 286013
URL: https://svnweb.freebsd.org/changeset/base/286013

Log:
  Eliminate the use of m_copydata() in gif_encapcheck().
  
  ip_encap already has inspected mbuf's data, at least an IP header.
  And it is safe to use mtod() and do direct access to needed fields.
  Add M_ASSERTPKTHDR() to gif_encapcheck(), since the code expects that
  mbuf has a packet header.
  Move the code from gif_validate[46] into in[6]_gif_encapcheck(), also
  remove "martian filters" checks. According to RFC 4213 it is enough to
  verify that the source address is the address of the encapsulator, as
  configured on the decapsulator.
  
  Reviewed by:	melifaro
  Obtained from:	Yandex LLC
  Sponsored by:	Yandex LLC

Modified:
  head/sys/net/if_gif.c
  head/sys/netinet/in_gif.c
  head/sys/netinet6/in6_gif.c

Modified: head/sys/net/if_gif.c
==============================================================================
--- head/sys/net/if_gif.c	Wed Jul 29 14:07:29 2015	(r286012)
+++ head/sys/net/if_gif.c	Wed Jul 29 14:07:43 2015	(r286013)
@@ -280,9 +280,9 @@ int
 gif_encapcheck(const struct mbuf *m, int off, int proto, void *arg)
 {
 	GIF_RLOCK_TRACKER;
+	const struct ip *ip;
 	struct gif_softc *sc;
 	int ret;
-	uint8_t ver;
 
 	sc = (struct gif_softc *)arg;
 	if (sc == NULL || (GIF2IFP(sc)->if_flags & IFF_UP) == 0)
@@ -309,11 +309,12 @@ gif_encapcheck(const struct mbuf *m, int
 	}
 
 	/* Bail on short packets */
+	M_ASSERTPKTHDR(m);
 	if (m->m_pkthdr.len < sizeof(struct ip))
 		goto done;
 
-	m_copydata(m, 0, 1, &ver);
-	switch (ver >> 4) {
+	ip = mtod(m, const struct ip *);
+	switch (ip->ip_v) {
 #ifdef INET
 	case 4:
 		if (sc->gif_family != AF_INET)

Modified: head/sys/netinet/in_gif.c
==============================================================================
--- head/sys/netinet/in_gif.c	Wed Jul 29 14:07:29 2015	(r286012)
+++ head/sys/netinet/in_gif.c	Wed Jul 29 14:07:43 2015	(r286013)
@@ -67,8 +67,6 @@ __FBSDID("$FreeBSD$");
 
 #include <net/if_gif.h>
 
-static int gif_validate4(const struct ip *, struct gif_softc *,
-	struct ifnet *);
 static int in_gif_input(struct mbuf **, int *, int);
 
 extern  struct domain inetdomain;
@@ -163,16 +161,22 @@ in_gif_input(struct mbuf **mp, int *offp
 }
 
 /*
- * validate outer address.
+ * we know that we are in IFF_UP, outer address available, and outer family
+ * matched the physical addr family.  see gif_encapcheck().
  */
-static int
-gif_validate4(const struct ip *ip, struct gif_softc *sc, struct ifnet *ifp)
+int
+in_gif_encapcheck(const struct mbuf *m, int off, int proto, void *arg)
 {
+	const struct ip *ip;
+	struct gif_softc *sc;
 	int ret;
 
+	/* sanity check done in caller */
+	sc = (struct gif_softc *)arg;
 	GIF_RLOCK_ASSERT(sc);
 
 	/* check for address match */
+	ip = mtod(m, const struct ip *);
 	if (sc->gif_iphdr->ip_src.s_addr != ip->ip_dst.s_addr)
 		return (0);
 	ret = 32;
@@ -182,18 +186,8 @@ gif_validate4(const struct ip *ip, struc
 	} else
 		ret += 32;
 
-	/* martian filters on outer source - NOT done in ip_input! */
-	if (IN_MULTICAST(ntohl(ip->ip_src.s_addr)))
-		return (0);
-	switch ((ntohl(ip->ip_src.s_addr) & 0xff000000) >> 24) {
-	case 0:
-	case 127:
-	case 255:
-		return (0);
-	}
-
 	/* ingress filters on outer source */
-	if ((GIF2IFP(sc)->if_flags & IFF_LINK2) == 0 && ifp) {
+	if ((GIF2IFP(sc)->if_flags & IFF_LINK2) == 0) {
 		struct sockaddr_in sin;
 		struct rtentry *rt;
 
@@ -204,8 +198,8 @@ gif_validate4(const struct ip *ip, struc
 		/* XXX MRT  check for the interface we would use on output */
 		rt = in_rtalloc1((struct sockaddr *)&sin, 0,
 		    0UL, sc->gif_fibnum);
-		if (!rt || rt->rt_ifp != ifp) {
-			if (rt)
+		if (rt == NULL || rt->rt_ifp != m->m_pkthdr.rcvif) {
+			if (rt != NULL)
 				RTFREE_LOCKED(rt);
 			return (0);
 		}
@@ -214,26 +208,6 @@ gif_validate4(const struct ip *ip, struc
 	return (ret);
 }
 
-/*
- * we know that we are in IFF_UP, outer address available, and outer family
- * matched the physical addr family.  see gif_encapcheck().
- */
-int
-in_gif_encapcheck(const struct mbuf *m, int off, int proto, void *arg)
-{
-	struct ip ip;
-	struct gif_softc *sc;
-	struct ifnet *ifp;
-
-	/* sanity check done in caller */
-	sc = (struct gif_softc *)arg;
-	GIF_RLOCK_ASSERT(sc);
-
-	m_copydata(m, 0, sizeof(ip), (caddr_t)&ip);
-	ifp = ((m->m_flags & M_PKTHDR) != 0) ? m->m_pkthdr.rcvif : NULL;
-	return (gif_validate4(&ip, sc, ifp));
-}
-
 int
 in_gif_attach(struct gif_softc *sc)
 {

Modified: head/sys/netinet6/in6_gif.c
==============================================================================
--- head/sys/netinet6/in6_gif.c	Wed Jul 29 14:07:29 2015	(r286012)
+++ head/sys/netinet6/in6_gif.c	Wed Jul 29 14:07:43 2015	(r286013)
@@ -81,8 +81,6 @@ SYSCTL_DECL(_net_inet6_ip6);
 SYSCTL_INT(_net_inet6_ip6, IPV6CTL_GIF_HLIM, gifhlim, CTLFLAG_VNET | CTLFLAG_RW,
     &VNET_NAME(ip6_gif_hlim), 0, "");
 
-static int gif_validate6(const struct ip6_hdr *, struct gif_softc *,
-			 struct ifnet *);
 static int in6_gif_input(struct mbuf **, int *, int);
 
 extern  struct domain inet6domain;
@@ -174,20 +172,26 @@ in6_gif_input(struct mbuf **mp, int *off
 }
 
 /*
- * validate outer address.
+ * we know that we are in IFF_UP, outer address available, and outer family
+ * matched the physical addr family.  see gif_encapcheck().
  */
-static int
-gif_validate6(const struct ip6_hdr *ip6, struct gif_softc *sc,
-    struct ifnet *ifp)
+int
+in6_gif_encapcheck(const struct mbuf *m, int off, int proto, void *arg)
 {
+	const struct ip6_hdr *ip6;
+	struct gif_softc *sc;
 	int ret;
 
+	/* sanity check done in caller */
+	sc = (struct gif_softc *)arg;
 	GIF_RLOCK_ASSERT(sc);
+
 	/*
 	 * Check for address match.  Note that the check is for an incoming
 	 * packet.  We should compare the *source* address in our configuration
 	 * and the *destination* address of the packet, and vice versa.
 	 */
+	ip6 = mtod(m, const struct ip6_hdr *);
 	if (!IN6_ARE_ADDR_EQUAL(&sc->gif_ip6hdr->ip6_src, &ip6->ip6_dst))
 		return (0);
 	ret = 128;
@@ -197,10 +201,8 @@ gif_validate6(const struct ip6_hdr *ip6,
 	} else
 		ret += 128;
 
-	/* martian filters on outer source - done in ip6_input */
-
 	/* ingress filters on outer source */
-	if ((GIF2IFP(sc)->if_flags & IFF_LINK2) == 0 && ifp) {
+	if ((GIF2IFP(sc)->if_flags & IFF_LINK2) == 0) {
 		struct sockaddr_in6 sin6;
 		struct rtentry *rt;
 
@@ -212,37 +214,16 @@ gif_validate6(const struct ip6_hdr *ip6,
 
 		rt = in6_rtalloc1((struct sockaddr *)&sin6, 0, 0UL,
 		    sc->gif_fibnum);
-		if (!rt || rt->rt_ifp != ifp) {
-			if (rt)
+		if (rt == NULL || rt->rt_ifp != m->m_pkthdr.rcvif) {
+			if (rt != NULL)
 				RTFREE_LOCKED(rt);
 			return (0);
 		}
 		RTFREE_LOCKED(rt);
 	}
-
 	return (ret);
 }
 
-/*
- * we know that we are in IFF_UP, outer address available, and outer family
- * matched the physical addr family.  see gif_encapcheck().
- */
-int
-in6_gif_encapcheck(const struct mbuf *m, int off, int proto, void *arg)
-{
-	struct ip6_hdr ip6;
-	struct gif_softc *sc;
-	struct ifnet *ifp;
-
-	/* sanity check done in caller */
-	sc = (struct gif_softc *)arg;
-	GIF_RLOCK_ASSERT(sc);
-
-	m_copydata(m, 0, sizeof(ip6), (caddr_t)&ip6);
-	ifp = ((m->m_flags & M_PKTHDR) != 0) ? m->m_pkthdr.rcvif : NULL;
-	return (gif_validate6(&ip6, sc, ifp));
-}
-
 int
 in6_gif_attach(struct gif_softc *sc)
 {


More information about the svn-src-head mailing list