in6_gif.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /* $OpenBSD: in6_gif.c,v 1.40 2015/06/16 11:09:40 mpi Exp $ */
  2. /* $KAME: in6_gif.c,v 1.43 2001/01/22 07:27:17 itojun Exp $ */
  3. /*
  4. * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the project nor the names of its contributors
  16. * may be used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  23. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. */
  31. #include "pf.h"
  32. #include <sys/param.h>
  33. #include <sys/systm.h>
  34. #include <sys/socket.h>
  35. #include <sys/sockio.h>
  36. #include <sys/mbuf.h>
  37. #include <sys/errno.h>
  38. #include <sys/ioctl.h>
  39. #include <sys/protosw.h>
  40. #include <net/if.h>
  41. #include <net/if_var.h>
  42. #include <netinet/in.h>
  43. #include <netinet/ip_ipsp.h>
  44. #if NPF > 0
  45. #include <net/pfvar.h>
  46. #endif
  47. #include <netinet/ip6.h>
  48. #include <netinet6/ip6_var.h>
  49. #include <netinet6/in6_gif.h>
  50. #include <netinet/ip_ecn.h>
  51. #include <net/if_gif.h>
  52. #include "bridge.h"
  53. #if NBRIDGE > 0 || defined(MPLS)
  54. #include <netinet/ip_ether.h>
  55. #endif
  56. /*
  57. * family - family of the packet to be encapsulate.
  58. */
  59. int
  60. in6_gif_output(struct ifnet *ifp, int family, struct mbuf **m0)
  61. {
  62. struct gif_softc *sc = (struct gif_softc*)ifp;
  63. struct sockaddr_in6 *sin6_src = satosin6(sc->gif_psrc);
  64. struct sockaddr_in6 *sin6_dst = satosin6(sc->gif_pdst);
  65. struct tdb tdb;
  66. struct xformsw xfs;
  67. int error;
  68. struct mbuf *m = *m0;
  69. if (sin6_src == NULL || sin6_dst == NULL ||
  70. sin6_src->sin6_family != AF_INET6 ||
  71. sin6_dst->sin6_family != AF_INET6) {
  72. m_freem(m);
  73. return EAFNOSUPPORT;
  74. }
  75. /* setup dummy tdb. it highly depends on ipip_output() code. */
  76. bzero(&tdb, sizeof(tdb));
  77. bzero(&xfs, sizeof(xfs));
  78. tdb.tdb_src.sin6.sin6_family = AF_INET6;
  79. tdb.tdb_src.sin6.sin6_len = sizeof(struct sockaddr_in6);
  80. tdb.tdb_src.sin6.sin6_addr = sin6_src->sin6_addr;
  81. tdb.tdb_dst.sin6.sin6_family = AF_INET6;
  82. tdb.tdb_dst.sin6.sin6_len = sizeof(struct sockaddr_in6);
  83. tdb.tdb_dst.sin6.sin6_addr = sin6_dst->sin6_addr;
  84. tdb.tdb_xform = &xfs;
  85. xfs.xf_type = -1; /* not XF_IP4 */
  86. switch (family) {
  87. case AF_INET:
  88. break;
  89. #ifdef INET6
  90. case AF_INET6:
  91. break;
  92. #endif
  93. #if NBRIDGE > 0
  94. case AF_LINK:
  95. break;
  96. #endif
  97. #ifdef MPLS
  98. case AF_MPLS:
  99. break;
  100. #endif
  101. default:
  102. #ifdef DEBUG
  103. printf("in6_gif_output: warning: unknown family %d passed\n",
  104. family);
  105. #endif
  106. m_freem(m);
  107. return EAFNOSUPPORT;
  108. }
  109. /* encapsulate into IPv6 packet */
  110. *m0 = NULL;
  111. #if NBRIDGE > 0
  112. if (family == AF_LINK)
  113. error = etherip_output(m, &tdb, m0, IPPROTO_ETHERIP);
  114. else
  115. #endif /* NBRIDGE */
  116. #if MPLS
  117. if (family == AF_MPLS)
  118. error = etherip_output(m, &tdb, m0, IPPROTO_MPLS);
  119. else
  120. #endif
  121. error = ipip_output(m, &tdb, m0, 0, 0);
  122. if (error)
  123. return error;
  124. else if (*m0 == NULL)
  125. return EFAULT;
  126. m = *m0;
  127. #if NPF > 0
  128. pf_pkt_addr_changed(m);
  129. #endif
  130. return 0;
  131. }
  132. int in6_gif_input(struct mbuf **mp, int *offp, int proto)
  133. {
  134. struct mbuf *m = *mp;
  135. struct gif_softc *sc;
  136. struct ifnet *gifp = NULL;
  137. struct ip6_hdr *ip6;
  138. /* XXX What if we run transport-mode IPsec to protect gif tunnel ? */
  139. if (m->m_flags & (M_AUTH | M_CONF))
  140. goto inject;
  141. ip6 = mtod(m, struct ip6_hdr *);
  142. #define satoin6(sa) (satosin6(sa)->sin6_addr)
  143. LIST_FOREACH(sc, &gif_softc_list, gif_list) {
  144. if (sc->gif_psrc == NULL || sc->gif_pdst == NULL ||
  145. sc->gif_psrc->sa_family != AF_INET6 ||
  146. sc->gif_pdst->sa_family != AF_INET6) {
  147. continue;
  148. }
  149. if ((sc->gif_if.if_flags & IFF_UP) == 0)
  150. continue;
  151. if (IN6_ARE_ADDR_EQUAL(&satoin6(sc->gif_psrc), &ip6->ip6_dst) &&
  152. IN6_ARE_ADDR_EQUAL(&satoin6(sc->gif_pdst), &ip6->ip6_src)) {
  153. gifp = &sc->gif_if;
  154. break;
  155. }
  156. }
  157. if (gifp) {
  158. m->m_pkthdr.ph_ifidx = gifp->if_index;
  159. gifp->if_ipackets++;
  160. gifp->if_ibytes += m->m_pkthdr.len;
  161. ipip_input(m, *offp, gifp, proto);
  162. return IPPROTO_DONE;
  163. }
  164. inject:
  165. /* No GIF tunnel configured */
  166. ip4_input6(&m, offp, proto);
  167. return IPPROTO_DONE;
  168. }