Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-5]: src/sys/net Pull up revisions 1.59-1.60, 1.62-1.65, 1.70 vi...
details: https://anonhg.NetBSD.org/src/rev/6386725c3b1d
branches: netbsd-1-5
changeset: 490458:6386725c3b1d
user: jhawk <jhawk%NetBSD.org@localhost>
date: Sun Dec 31 20:14:28 2000 +0000
description:
Pull up revisions 1.59-1.60, 1.62-1.65, 1.70 via patch (requested by bouyer):
Add support for 802.1Q virtual LANs.
diffstat:
sys/net/if_ethersubr.c | 276 ++++++++++++++++++++++++++++--------------------
1 files changed, 158 insertions(+), 118 deletions(-)
diffs (truncated from 356 to 300 lines):
diff -r 6c2eef70d8d0 -r 6386725c3b1d sys/net/if_ethersubr.c
--- a/sys/net/if_ethersubr.c Sun Dec 31 20:14:25 2000 +0000
+++ b/sys/net/if_ethersubr.c Sun Dec 31 20:14:28 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ethersubr.c,v 1.58 2000/06/17 20:57:20 matt Exp $ */
+/* $NetBSD: if_ethersubr.c,v 1.58.2.1 2000/12/31 20:14:28 jhawk Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -71,6 +71,7 @@
#include "opt_iso.h"
#include "opt_ns.h"
#include "opt_gateway.h"
+#include "vlan.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -93,6 +94,9 @@
#include <net/if_types.h>
#include <net/if_ether.h>
+#if NVLAN > 0
+#include <net/if_vlanvar.h>
+#endif
#include <netinet/in.h>
#ifdef INET
@@ -497,6 +501,7 @@
u_int16_t etype;
int s;
struct ether_header *eh;
+ struct mbuf *n;
#if defined (ISO) || defined (LLC) || defined(NETATALK)
struct llc *l;
#endif
@@ -507,6 +512,16 @@
}
eh = mtod(m, struct ether_header *);
+ etype = ntohs(eh->ether_type);
+
+ /*
+ * Determine if the packet is within its size limits.
+ */
+ if (m->m_pkthdr.len > ETHER_MAX_FRAME(etype, m->m_flags & M_HASFCS)) {
+ printf("%s: discarding oversize frame\n", ifp->if_xname);
+ m_freem(m);
+ return;
+ }
ifp->if_lastchange = time;
ifp->if_ibytes += m->m_pkthdr.len;
@@ -516,11 +531,50 @@
m->m_flags |= M_BCAST;
else
m->m_flags |= M_MCAST;
+ ifp->if_imcasts++;
+ } else if ((ifp->if_flags & IFF_PROMISC) != 0 &&
+ memcmp(LLADDR(ifp->if_sadl), eh->ether_dhost,
+ ETHER_ADDR_LEN) != 0) {
+ m_freem(m);
+ return;
}
- if (m->m_flags & (M_BCAST|M_MCAST))
- ifp->if_imcasts++;
+
+ /* Check if the mbuf has a VLAN tag */
+ n = m_aux_find(m, AF_LINK, ETHERTYPE_VLAN);
+ if (n) {
+#if NVLAN > 0
+ /*
+ * vlan_input() will either recursively call ether_input()
+ * or drop the packet.
+ */
+ if (((struct ethercom *)ifp)->ec_nvlans != 0)
+ vlan_input(ifp, m);
+ else
+#endif
+ m_freem(m);
+ return;
+ }
- etype = ntohs(eh->ether_type);
+ /*
+ * Handle protocols that expect to have the Ethernet header
+ * (and possibly FCS) intact.
+ */
+ switch (etype) {
+#if NVLAN > 0
+ case ETHERTYPE_VLAN:
+ /*
+ * vlan_input() will either recursively call ether_input()
+ * or drop the packet.
+ */
+ if (((struct ethercom *)ifp)->ec_nvlans != 0)
+ vlan_input(ifp, m);
+ else
+ m_freem(m);
+ return;
+#endif /* NVLAN > 0 */
+ default:
+ /* Nothing. */
+ }
/* Strip off the Ethernet header. */
m_adj(m, sizeof(struct ether_header));
@@ -776,8 +830,27 @@
void
ether_ifdetach(struct ifnet *ifp)
{
+ struct ethercom *ec = (void *) ifp;
+ struct sockaddr_dl *sdl = ifp->if_sadl;
+ struct ether_multi *enm;
+ int s;
- /* Nothing. */
+#if NVLAN > 0
+ if (ec->ec_nvlans)
+ vlan_ifdetach(ifp);
+#endif
+
+ s = splimp();
+ while ((enm = LIST_FIRST(&ec->ec_multiaddrs)) != NULL) {
+ LIST_REMOVE(enm, enm_list);
+ free(enm, M_IFADDR);
+ ec->ec_multicnt--;
+ }
+ splx(s);
+
+ memset(LLADDR(sdl), 0, ETHER_ADDR_LEN);
+ sdl->sdl_alen = 0;
+ sdl->sdl_type = 0;
}
#if 0
@@ -862,6 +935,73 @@
u_char ether_ip6multicast_min[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
u_char ether_ip6multicast_max[6] = { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
#endif
+
+/*
+ * Convert a sockaddr into an Ethernet address or range of Ethernet
+ * addresses.
+ */
+int
+ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN],
+ u_int8_t addrhi[ETHER_ADDR_LEN])
+{
+#ifdef INET
+ struct sockaddr_in *sin;
+#endif /* INET */
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+#endif /* INET6 */
+
+ switch (sa->sa_family) {
+
+ case AF_UNSPEC:
+ bcopy(sa->sa_data, addrlo, ETHER_ADDR_LEN);
+ bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
+ break;
+
+#ifdef INET
+ case AF_INET:
+ sin = satosin(sa);
+ if (sin->sin_addr.s_addr == INADDR_ANY) {
+ /*
+ * An IP address of INADDR_ANY means listen to
+ * or stop listening to all of the Ethernet
+ * multicast addresses used for IP.
+ * (This is for the sake of IP multicast routers.)
+ */
+ bcopy(ether_ipmulticast_min, addrlo, ETHER_ADDR_LEN);
+ bcopy(ether_ipmulticast_max, addrhi, ETHER_ADDR_LEN);
+ }
+ else {
+ ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
+ bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
+ }
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ sin6 = satosin6(sa);
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ /*
+ * An IP6 address of 0 means listen to or stop
+ * listening to all of the Ethernet multicast
+ * address used for IP6.
+ * (This is used for multicast routers.)
+ */
+ bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
+ bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
+ } else {
+ ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
+ bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
+ }
+ break;
+#endif
+
+ default:
+ return (EAFNOSUPPORT);
+ }
+ return (0);
+}
+
/*
* Add an Ethernet multicast address or range of addresses to the list for a
* given interface.
@@ -870,66 +1010,14 @@
ether_addmulti(struct ifreq *ifr, struct ethercom *ec)
{
struct ether_multi *enm;
-#ifdef INET
- struct sockaddr_in *sin;
-#endif /* INET */
-#ifdef INET6
- struct sockaddr_in6 *sin6;
-#endif /* INET6 */
- u_char addrlo[6];
- u_char addrhi[6];
- int s = splimp();
-
- switch (ifr->ifr_addr.sa_family) {
-
- case AF_UNSPEC:
- bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
- bcopy(addrlo, addrhi, 6);
- break;
+ u_char addrlo[ETHER_ADDR_LEN];
+ u_char addrhi[ETHER_ADDR_LEN];
+ int s = splimp(), error;
-#ifdef INET
- case AF_INET:
- sin = (struct sockaddr_in *)&(ifr->ifr_addr);
- if (sin->sin_addr.s_addr == INADDR_ANY) {
- /*
- * An IP address of INADDR_ANY means listen to all
- * of the Ethernet multicast addresses used for IP.
- * (This is for the sake of IP multicast routers.)
- */
- bcopy(ether_ipmulticast_min, addrlo, 6);
- bcopy(ether_ipmulticast_max, addrhi, 6);
- }
- else {
- ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
- bcopy(addrlo, addrhi, 6);
- }
- break;
-#endif
-#ifdef INET6
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *)
- &(((struct in6_ifreq *)ifr)->ifr_addr);
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
- /*
- * An IP6 address of 0 means listen to all
- * of the Ethernet multicast address used for IP6.
- * (This is used for multicast routers.)
- */
- bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
- bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
-#if 0
- set_allmulti = 1;
-#endif
- } else {
- ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
- bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
- }
- break;
-#endif
-
- default:
+ error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
+ if (error != 0) {
splx(s);
- return (EAFNOSUPPORT);
+ return (error);
}
/*
@@ -981,66 +1069,18 @@
ether_delmulti(struct ifreq *ifr, struct ethercom *ec)
{
struct ether_multi *enm;
-#ifdef INET
- struct sockaddr_in *sin;
-#endif /* INET */
-#ifdef INET6
- struct sockaddr_in6 *sin6;
-#endif /* INET6 */
- u_char addrlo[6];
- u_char addrhi[6];
- int s = splimp();
-
- switch (ifr->ifr_addr.sa_family) {
-
- case AF_UNSPEC:
- bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
Home |
Main Index |
Thread Index |
Old Index