if_vether.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /* $OpenBSD: if_vether.c,v 1.24 2015/05/23 08:31:05 mpi Exp $ */
  2. /*
  3. * Copyright (c) 2009 Theo de Raadt
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. #include <sys/param.h>
  18. #include <sys/systm.h>
  19. #include <sys/mbuf.h>
  20. #include <sys/socket.h>
  21. #include <sys/sockio.h>
  22. #include <sys/ioctl.h>
  23. #include <net/if.h>
  24. #include <net/if_media.h>
  25. #include <netinet/in.h>
  26. #include <netinet/if_ether.h>
  27. #include "bpfilter.h"
  28. #if NBPFILTER > 0
  29. #include <net/bpf.h>
  30. #endif
  31. void vetherattach(int);
  32. int vetherioctl(struct ifnet *, u_long, caddr_t);
  33. void vetherstart(struct ifnet *);
  34. int vether_clone_create(struct if_clone *, int);
  35. int vether_clone_destroy(struct ifnet *);
  36. int vether_media_change(struct ifnet *);
  37. void vether_media_status(struct ifnet *, struct ifmediareq *);
  38. struct vether_softc {
  39. struct arpcom sc_ac;
  40. struct ifmedia sc_media;
  41. };
  42. struct if_clone vether_cloner =
  43. IF_CLONE_INITIALIZER("vether", vether_clone_create, vether_clone_destroy);
  44. int
  45. vether_media_change(struct ifnet *ifp)
  46. {
  47. return (0);
  48. }
  49. void
  50. vether_media_status(struct ifnet *ifp, struct ifmediareq *imr)
  51. {
  52. imr->ifm_active = IFM_ETHER | IFM_AUTO;
  53. imr->ifm_status = IFM_AVALID | IFM_ACTIVE;
  54. }
  55. void
  56. vetherattach(int nvether)
  57. {
  58. if_clone_attach(&vether_cloner);
  59. }
  60. int
  61. vether_clone_create(struct if_clone *ifc, int unit)
  62. {
  63. struct ifnet *ifp;
  64. struct vether_softc *sc;
  65. if ((sc = malloc(sizeof(*sc),
  66. M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
  67. return (ENOMEM);
  68. ifp = &sc->sc_ac.ac_if;
  69. snprintf(ifp->if_xname, sizeof ifp->if_xname, "vether%d", unit);
  70. ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  71. ether_fakeaddr(ifp);
  72. ifp->if_softc = sc;
  73. ifp->if_ioctl = vetherioctl;
  74. ifp->if_start = vetherstart;
  75. IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
  76. IFQ_SET_READY(&ifp->if_snd);
  77. ifp->if_capabilities = IFCAP_VLAN_MTU;
  78. ifmedia_init(&sc->sc_media, 0, vether_media_change,
  79. vether_media_status);
  80. ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
  81. ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
  82. if_attach(ifp);
  83. ether_ifattach(ifp);
  84. return (0);
  85. }
  86. int
  87. vether_clone_destroy(struct ifnet *ifp)
  88. {
  89. struct vether_softc *sc = ifp->if_softc;
  90. ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
  91. ether_ifdetach(ifp);
  92. if_detach(ifp);
  93. free(sc, M_DEVBUF, sizeof(*sc));
  94. return (0);
  95. }
  96. /*
  97. * The bridge has magically already done all the work for us,
  98. * and we only need to discard the packets.
  99. */
  100. void
  101. vetherstart(struct ifnet *ifp)
  102. {
  103. struct mbuf *m;
  104. for (;;) {
  105. IFQ_DEQUEUE(&ifp->if_snd, m);
  106. if (m == NULL)
  107. return;
  108. #if NBPFILTER > 0
  109. if (ifp->if_bpf)
  110. bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
  111. #endif /* NBPFILTER > 0 */
  112. ifp->if_opackets++;
  113. m_freem(m);
  114. }
  115. }
  116. /* ARGSUSED */
  117. int
  118. vetherioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  119. {
  120. struct vether_softc *sc = (struct vether_softc *)ifp->if_softc;
  121. struct ifaddr *ifa = (struct ifaddr *)data;
  122. struct ifreq *ifr = (struct ifreq *)data;
  123. int error = 0, link_state;
  124. switch (cmd) {
  125. case SIOCSIFADDR:
  126. ifp->if_flags |= IFF_UP;
  127. if (ifa->ifa_addr->sa_family == AF_INET)
  128. arp_ifinit(&sc->sc_ac, ifa);
  129. /* FALLTHROUGH */
  130. case SIOCSIFFLAGS:
  131. if (ifp->if_flags & IFF_UP) {
  132. ifp->if_flags |= IFF_RUNNING;
  133. link_state = LINK_STATE_UP;
  134. } else {
  135. ifp->if_flags &= ~IFF_RUNNING;
  136. link_state = LINK_STATE_DOWN;
  137. }
  138. if (ifp->if_link_state != link_state) {
  139. ifp->if_link_state = link_state;
  140. if_link_state_change(ifp);
  141. }
  142. break;
  143. case SIOCADDMULTI:
  144. case SIOCDELMULTI:
  145. break;
  146. case SIOCGIFMEDIA:
  147. case SIOCSIFMEDIA:
  148. error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
  149. break;
  150. default:
  151. error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
  152. }
  153. return (error);
  154. }