if_loop.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /* $OpenBSD: if_loop.c,v 1.70 2015/07/29 00:04:03 rzalamena Exp $ */
  2. /* $NetBSD: if_loop.c,v 1.15 1996/05/07 02:40:33 thorpej 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. /*
  32. * Copyright (c) 1982, 1986, 1993
  33. * The Regents of the University of California. All rights reserved.
  34. *
  35. * Redistribution and use in source and binary forms, with or without
  36. * modification, are permitted provided that the following conditions
  37. * are met:
  38. * 1. Redistributions of source code must retain the above copyright
  39. * notice, this list of conditions and the following disclaimer.
  40. * 2. Redistributions in binary form must reproduce the above copyright
  41. * notice, this list of conditions and the following disclaimer in the
  42. * documentation and/or other materials provided with the distribution.
  43. * 3. Neither the name of the University nor the names of its contributors
  44. * may be used to endorse or promote products derived from this software
  45. * without specific prior written permission.
  46. *
  47. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  48. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  49. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  50. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  51. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  52. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  53. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  54. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  55. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  56. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  57. * SUCH DAMAGE.
  58. *
  59. * @(#)if_loop.c 8.1 (Berkeley) 6/10/93
  60. */
  61. /*
  62. * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
  63. *
  64. * NRL grants permission for redistribution and use in source and binary
  65. * forms, with or without modification, of the software and documentation
  66. * created at NRL provided that the following conditions are met:
  67. *
  68. * 1. Redistributions of source code must retain the above copyright
  69. * notice, this list of conditions and the following disclaimer.
  70. * 2. Redistributions in binary form must reproduce the above copyright
  71. * notice, this list of conditions and the following disclaimer in the
  72. * documentation and/or other materials provided with the distribution.
  73. * 3. All advertising materials mentioning features or use of this software
  74. * must display the following acknowledgements:
  75. * This product includes software developed by the University of
  76. * California, Berkeley and its contributors.
  77. * This product includes software developed at the Information
  78. * Technology Division, US Naval Research Laboratory.
  79. * 4. Neither the name of the NRL nor the names of its contributors
  80. * may be used to endorse or promote products derived from this software
  81. * without specific prior written permission.
  82. *
  83. * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
  84. * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  85. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  86. * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR
  87. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  88. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  89. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  90. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  91. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  92. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  93. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  94. *
  95. * The views and conclusions contained in the software and documentation
  96. * are those of the authors and should not be interpreted as representing
  97. * official policies, either expressed or implied, of the US Naval
  98. * Research Laboratory (NRL).
  99. */
  100. /*
  101. * Loopback interface driver for protocol testing and timing.
  102. */
  103. #include "bpfilter.h"
  104. #include <sys/param.h>
  105. #include <sys/systm.h>
  106. #include <sys/kernel.h>
  107. #include <sys/mbuf.h>
  108. #include <sys/socket.h>
  109. #include <sys/errno.h>
  110. #include <sys/ioctl.h>
  111. #include <sys/time.h>
  112. #include <net/if.h>
  113. #include <net/if_var.h>
  114. #include <net/if_types.h>
  115. #include <net/netisr.h>
  116. #include <net/route.h>
  117. #include <netinet/in.h>
  118. #ifdef INET6
  119. #include <netinet/ip6.h>
  120. #endif
  121. #ifdef MPLS
  122. #include <netmpls/mpls.h>
  123. #endif
  124. #if NBPFILTER > 0
  125. #include <net/bpf.h>
  126. #endif
  127. #define LOMTU 32768
  128. int loop_clone_create(struct if_clone *, int);
  129. int loop_clone_destroy(struct ifnet *);
  130. struct if_clone loop_cloner =
  131. IF_CLONE_INITIALIZER("lo", loop_clone_create, loop_clone_destroy);
  132. /* ARGSUSED */
  133. void
  134. loopattach(int n)
  135. {
  136. if (loop_clone_create(&loop_cloner, 0))
  137. panic("unable to create lo0");
  138. if_clone_attach(&loop_cloner);
  139. }
  140. int
  141. loop_clone_create(struct if_clone *ifc, int unit)
  142. {
  143. struct ifnet *ifp;
  144. ifp = malloc(sizeof(*ifp), M_DEVBUF, M_NOWAIT|M_ZERO);
  145. if (ifp == NULL)
  146. return (ENOMEM);
  147. snprintf(ifp->if_xname, sizeof ifp->if_xname, "lo%d", unit);
  148. ifp->if_softc = NULL;
  149. ifp->if_mtu = LOMTU;
  150. ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
  151. ifp->if_ioctl = loioctl;
  152. ifp->if_output = looutput;
  153. ifp->if_type = IFT_LOOP;
  154. ifp->if_hdrlen = sizeof(u_int32_t);
  155. ifp->if_addrlen = 0;
  156. IFQ_SET_READY(&ifp->if_snd);
  157. if (unit == 0) {
  158. lo0ifp = ifp;
  159. if_attachhead(ifp);
  160. if_addgroup(lo0ifp, ifc->ifc_name);
  161. } else
  162. if_attach(ifp);
  163. if_alloc_sadl(ifp);
  164. #if NBPFILTER > 0
  165. bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t));
  166. #endif
  167. return (0);
  168. }
  169. int
  170. loop_clone_destroy(struct ifnet *ifp)
  171. {
  172. if (ifp == lo0ifp)
  173. return (EPERM);
  174. if_detach(ifp);
  175. free(ifp, M_DEVBUF, sizeof(*ifp));
  176. return (0);
  177. }
  178. int
  179. looutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
  180. struct rtentry *rt)
  181. {
  182. struct niqueue *ifq = NULL;
  183. if ((m->m_flags & M_PKTHDR) == 0)
  184. panic("looutput: no header mbuf");
  185. #if NBPFILTER > 0
  186. /*
  187. * only send packets to bpf if they are real loopback packets;
  188. * looutput() is also called for SIMPLEX interfaces to duplicate
  189. * packets for local use. But don't dup them to bpf.
  190. */
  191. if (ifp->if_bpf && (ifp->if_flags & IFF_LOOPBACK))
  192. bpf_mtap_af(ifp->if_bpf, dst->sa_family, m, BPF_DIRECTION_OUT);
  193. #endif
  194. m->m_pkthdr.ph_ifidx = ifp->if_index;
  195. if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
  196. m_freem(m);
  197. return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
  198. rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
  199. }
  200. ifp->if_opackets++;
  201. ifp->if_obytes += m->m_pkthdr.len;
  202. switch (dst->sa_family) {
  203. case AF_INET:
  204. ifq = &ipintrq;
  205. break;
  206. #ifdef INET6
  207. case AF_INET6:
  208. ifq = &ip6intrq;
  209. break;
  210. #endif /* INET6 */
  211. #ifdef MPLS
  212. case AF_MPLS:
  213. ifp->if_ipackets++;
  214. ifp->if_ibytes += m->m_pkthdr.len;
  215. mpls_input(ifp, m);
  216. return (0);
  217. #endif /* MPLS */
  218. default:
  219. printf("%s: can't handle af%d\n", ifp->if_xname,
  220. dst->sa_family);
  221. m_freem(m);
  222. return (EAFNOSUPPORT);
  223. }
  224. if (niq_enqueue(ifq, m) != 0)
  225. return (ENOBUFS);
  226. ifp->if_ipackets++;
  227. ifp->if_ibytes += m->m_pkthdr.len;
  228. return (0);
  229. }
  230. /* ARGSUSED */
  231. void
  232. lortrequest(int cmd, struct rtentry *rt)
  233. {
  234. if (rt && rt->rt_rmx.rmx_mtu == 0)
  235. rt->rt_rmx.rmx_mtu = LOMTU;
  236. }
  237. /*
  238. * Process an ioctl request.
  239. */
  240. /* ARGSUSED */
  241. int
  242. loioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  243. {
  244. struct ifaddr *ifa;
  245. struct ifreq *ifr;
  246. int error = 0;
  247. switch (cmd) {
  248. case SIOCSIFADDR:
  249. ifp->if_flags |= IFF_RUNNING;
  250. if_up(ifp); /* send up RTM_IFINFO */
  251. ifa = (struct ifaddr *)data;
  252. if (ifa != 0)
  253. ifa->ifa_rtrequest = lortrequest;
  254. /*
  255. * Everything else is done at a higher level.
  256. */
  257. break;
  258. case SIOCADDMULTI:
  259. case SIOCDELMULTI:
  260. break;
  261. case SIOCSIFMTU:
  262. ifr = (struct ifreq *)data;
  263. ifp->if_mtu = ifr->ifr_mtu;
  264. break;
  265. default:
  266. error = ENOTTY;
  267. }
  268. return (error);
  269. }