From 6860ef65ebb48cad51b7d4caa34fb4f0e4ebbcbc Mon Sep 17 00:00:00 2001 From: bz Date: Mon, 1 Aug 2005 08:14:21 +0000 Subject: [PATCH] Add support for IPv6 over GRE [1]. PR kern/80340 includes the FreeBSD specific ip_newid() changes NetBSD does not have. Correct handling of non AF_INET packets passed to bpf [2]. PR: kern/80340[1], NetBSD PRs 29150[1], 30844[2] Obtained from: NetBSD ip_gre.c rev. 1.34,1.35, if_gre.c rev. 1.56 Submitted by: Gert Doering [2] MFC after: 4 days --- sys/net/if_gre.c | 22 +++++++++++++++++++--- sys/netinet/ip_gre.c | 15 ++++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 90f54c980e06..dc7355d21edc 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -8,6 +8,8 @@ * This code is derived from software contributed to The NetBSD Foundation * by Heiko W.Rupp * + * IPv6-over-GRE contributed by Gert Doering + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -39,7 +41,7 @@ /* * Encapsulate L3 protocols into IP - * See RFC 1701 and 1702 for more details. + * See RFC 2784 (successor of RFC 1701 and 1702) for more details. * If_gre is compatible with Cisco GRE tunnels, so you can * have a NetBSD box as the other end of a tunnel interface of a Cisco * router. See gre(4) for more details. @@ -237,6 +239,8 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct gre_softc *sc = ifp->if_softc; struct greip *gh; struct ip *ip; + u_short ip_id = 0; + uint8_t ip_tos = 0; u_int16_t etype = 0; struct mobile_h mob_h; u_int32_t af; @@ -352,8 +356,16 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, switch (dst->sa_family) { case AF_INET: ip = mtod(m, struct ip *); + ip_tos = ip->ip_tos; + ip_id = ip->ip_id; etype = ETHERTYPE_IP; break; +#ifdef INET6 + case AF_INET6: + ip_id = ip_newid(); + etype = ETHERTYPE_IPV6; + break; +#endif #ifdef NETATALK case AF_APPLETALK: etype = ETHERTYPE_ATALK; @@ -393,8 +405,8 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, ((struct ip*)gh)->ip_v = IPPROTO_IPV4; ((struct ip*)gh)->ip_hl = (sizeof(struct ip)) >> 2; ((struct ip*)gh)->ip_ttl = GRE_TTL; - ((struct ip*)gh)->ip_tos = ip->ip_tos; - ((struct ip*)gh)->ip_id = ip->ip_id; + ((struct ip*)gh)->ip_tos = ip_tos; + ((struct ip*)gh)->ip_id = ip_id; gh->gi_len = m->m_pkthdr.len; } @@ -472,6 +484,10 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) #ifdef INET case AF_INET: break; +#endif +#ifdef INET6 + case AF_INET6: + break; #endif default: error = EAFNOSUPPORT; diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c index 230472293fc3..04dc3d932ad9 100644 --- a/sys/netinet/ip_gre.c +++ b/sys/netinet/ip_gre.c @@ -8,6 +8,8 @@ * This code is derived from software contributed to The NetBSD Foundation * by Heiko W.Rupp * + * IPv6-over-GRE contributed by Gert Doering + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -45,6 +47,7 @@ #include "opt_inet.h" #include "opt_atalk.h" +#include "opt_inet6.h" #include #include @@ -142,6 +145,7 @@ gre_input2(struct mbuf *m ,int hlen, u_char proto) int isr; struct gre_softc *sc; u_int16_t flags; + u_int32_t af; if ((sc = gre_lookup(m, proto)) == NULL) { /* No matching tunnel or tunnel is down. */ @@ -183,14 +187,20 @@ gre_input2(struct mbuf *m ,int hlen, u_char proto) /* FALLTHROUGH */ case ETHERTYPE_IP: /* shouldn't need a schednetisr(), */ isr = NETISR_IP;/* as we are in ip_input */ + af = AF_INET; break; +#ifdef INET6 + case ETHERTYPE_IPV6: + isr = NETISR_IPV6; + af = AF_INET6; + break; +#endif #ifdef NETATALK case ETHERTYPE_ATALK: isr = NETISR_ATALK1; + af = AF_APPLETALK; break; #endif - case ETHERTYPE_IPV6: - /* FALLTHROUGH */ default: /* others not yet supported */ return (0); } @@ -208,7 +218,6 @@ gre_input2(struct mbuf *m ,int hlen, u_char proto) m_adj(m, hlen); if (GRE2IFP(sc)->if_bpf) { - u_int32_t af = AF_INET; bpf_mtap2(GRE2IFP(sc)->if_bpf, &af, sizeof(af), m); }