summaryrefslogtreecommitdiffstats
path: root/sys/netinet/in_gif.c
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2002-10-16 19:49:37 +0000
committerume <ume@FreeBSD.org>2002-10-16 19:49:37 +0000
commit2bb6ef9a3f703f5e4ce9650638cad001d0e9d3f8 (patch)
treeef5672e1d755fcae3719333087302d3e50123b72 /sys/netinet/in_gif.c
parent12d5a1b9ff26477521c7a00578228c90d54d9ae1 (diff)
downloadFreeBSD-src-2bb6ef9a3f703f5e4ce9650638cad001d0e9d3f8.zip
FreeBSD-src-2bb6ef9a3f703f5e4ce9650638cad001d0e9d3f8.tar.gz
- after gif_set_tunnel(), psrc/pdst may be null. set IFF_RUNNING accordingly.
- set IFF_UP on SIOCSIFADDR. be consistent with others. - set if_addrlen explicitly (just in case) - multi destination mode is long gone. - missing break statement - add gif_set_tunnel(), so that we can set tunnel address from within the kernel at ease. - encap_attach/detach dynamically on ioctls - move encap_attach() to dedicated function in in*_gif.c Obtained from: KAME MFC after: 3 weeks
Diffstat (limited to 'sys/netinet/in_gif.c')
-rw-r--r--sys/netinet/in_gif.c118
1 files changed, 89 insertions, 29 deletions
diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c
index ffd877b..d6508d5 100644
--- a/sys/netinet/in_gif.c
+++ b/sys/netinet/in_gif.c
@@ -42,6 +42,7 @@
#include <sys/errno.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
+#include <sys/protosw.h>
#include <sys/malloc.h>
@@ -69,6 +70,18 @@
#include <net/net_osdep.h>
+static int gif_validate4(const struct ip *, struct gif_softc *,
+ struct ifnet *);
+
+extern struct domain inetdomain;
+struct protosw in_gif_protosw =
+{ SOCK_RAW, &inetdomain, 0/*IPPROTO_IPV[46]*/, PR_ATOMIC|PR_ADDR,
+ in_gif_input, (pr_output_t*)rip_output, 0, rip_ctloutput,
+ 0,
+ 0, 0, 0, 0,
+ &rip_usrreqs
+};
+
static int ip_gif_ttl = GIF_TTL;
SYSCTL_INT(_net_inet_ip, IPCTL_GIF_TTL, gifttl, CTLFLAG_RW,
&ip_gif_ttl, 0, "");
@@ -277,43 +290,29 @@ in_gif_input(m, off)
}
/*
- * we know that we are in IFF_UP, outer address available, and outer family
- * matched the physical addr family. see gif_encapcheck().
+ * validate outer address.
*/
-int
-gif_encapcheck4(m, off, proto, arg)
- const struct mbuf *m;
- int off;
- int proto;
- void *arg;
-{
- struct ip ip;
+static int
+gif_validate4(ip, sc, ifp)
+ const struct ip *ip;
struct gif_softc *sc;
+ struct ifnet *ifp;
+{
struct sockaddr_in *src, *dst;
- int addrmatch;
struct in_ifaddr *ia4;
- /* sanity check done in caller */
- sc = (struct gif_softc *)arg;
src = (struct sockaddr_in *)sc->gif_psrc;
dst = (struct sockaddr_in *)sc->gif_pdst;
- /* LINTED const cast */
- m_copydata(m, 0, sizeof(ip), (caddr_t)&ip);
-
/* check for address match */
- addrmatch = 0;
- if (src->sin_addr.s_addr == ip.ip_dst.s_addr)
- addrmatch |= 1;
- if (dst->sin_addr.s_addr == ip.ip_src.s_addr)
- addrmatch |= 2;
- if (addrmatch != 3)
+ if (src->sin_addr.s_addr != ip->ip_dst.s_addr ||
+ dst->sin_addr.s_addr != ip->ip_src.s_addr)
return 0;
/* martian filters on outer source - NOT done in ip_input! */
- if (IN_MULTICAST(ntohl(ip.ip_src.s_addr)))
+ if (IN_MULTICAST(ntohl(ip->ip_src.s_addr)))
return 0;
- switch ((ntohl(ip.ip_src.s_addr) & 0xff000000) >> 24) {
+ switch ((ntohl(ip->ip_src.s_addr) & 0xff000000) >> 24) {
case 0: case 127: case 255:
return 0;
}
@@ -322,22 +321,21 @@ gif_encapcheck4(m, off, proto, arg)
{
if ((ia4->ia_ifa.ifa_ifp->if_flags & IFF_BROADCAST) == 0)
continue;
- if (ip.ip_src.s_addr == ia4->ia_broadaddr.sin_addr.s_addr)
+ if (ip->ip_src.s_addr == ia4->ia_broadaddr.sin_addr.s_addr)
return 0;
}
/* ingress filters on outer source */
- if ((sc->gif_if.if_flags & IFF_LINK2) == 0 &&
- (m->m_flags & M_PKTHDR) != 0 && m->m_pkthdr.rcvif) {
+ if ((sc->gif_if.if_flags & IFF_LINK2) == 0 && ifp) {
struct sockaddr_in sin;
struct rtentry *rt;
bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_len = sizeof(struct sockaddr_in);
- sin.sin_addr = ip.ip_src;
+ sin.sin_addr = ip->ip_src;
rt = rtalloc1((struct sockaddr *)&sin, 0, 0UL);
- if (!rt || rt->rt_ifp != m->m_pkthdr.rcvif) {
+ if (!rt || rt->rt_ifp != ifp) {
#if 0
log(LOG_WARNING, "%s: packet from 0x%x dropped "
"due to ingress filter\n", if_name(&sc->gif_if),
@@ -352,3 +350,65 @@ gif_encapcheck4(m, off, proto, arg)
return 32 * 2;
}
+
+/*
+ * we know that we are in IFF_UP, outer address available, and outer family
+ * matched the physical addr family. see gif_encapcheck().
+ */
+int
+gif_encapcheck4(m, off, proto, arg)
+ 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;
+
+ /* LINTED const cast */
+ 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(sc)
+ struct gif_softc *sc;
+{
+#ifndef USE_ENCAPCHECK
+ struct sockaddr_in mask4;
+
+ bzero(&mask4, sizeof(mask4));
+ mask4.sin_len = sizeof(struct sockaddr_in);
+ mask4.sin_addr.s_addr = ~0;
+
+ if (!sc->gif_psrc || !sc->gif_pdst)
+ return EINVAL;
+ sc->encap_cookie4 = encap_attach(AF_INET, -1, sc->gif_psrc,
+ (struct sockaddr *)&mask4, sc->gif_pdst, (struct sockaddr *)&mask4,
+ (struct protosw *)&in_gif_protosw, sc);
+#else
+ sc->encap_cookie4 = encap_attach_func(AF_INET, -1, gif_encapcheck,
+ &in_gif_protosw, sc);
+#endif
+ if (sc->encap_cookie4 == NULL)
+ return EEXIST;
+ return 0;
+}
+
+int
+in_gif_detach(sc)
+ struct gif_softc *sc;
+{
+ int error;
+
+ error = encap_detach(sc->encap_cookie4);
+ if (error == 0)
+ sc->encap_cookie4 = NULL;
+ return error;
+}
OpenPOWER on IntegriCloud