summaryrefslogtreecommitdiffstats
path: root/sys/net/if_ethersubr.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/if_ethersubr.c')
-rw-r--r--sys/net/if_ethersubr.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index f84c7d65d9c..c39d5f3a5e7 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ethersubr.c,v 1.117 2008/04/18 09:16:14 djm Exp $ */
+/* $OpenBSD: if_ethersubr.c,v 1.118 2008/04/23 10:55:14 norby Exp $ */
/* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */
/*
@@ -150,6 +150,10 @@ extern u_char at_org_code[ 3 ];
extern u_char aarp_org_code[ 3 ];
#endif /* NETATALK */
+#ifdef MPLS
+#include <netmpls/mpls.h>
+#endif /* MPLS */
+
u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
#define senderr(e) { error = (e); goto bad;}
@@ -325,6 +329,33 @@ ether_output(ifp0, m0, dst, rt0)
}
} break;
#endif /* NETATALK */
+#ifdef MPLS
+ case AF_MPLS:
+ if (rt)
+ dst = (struct sockaddr *)rt->rt_gateway;
+ else
+ senderr(EHOSTUNREACH);
+
+ switch (dst->sa_family) {
+ case AF_LINK:
+ if (satosdl(dst)->sdl_alen < sizeof(edst))
+ senderr(EHOSTUNREACH);
+ bcopy(LLADDR(satosdl(dst)), edst, sizeof(edst));
+ break;
+ case AF_INET:
+ if (!arpresolve(ac, rt, m, dst, edst))
+ return (0); /* if not yet resolved */
+ break;
+ default:
+ senderr(EHOSTUNREACH);
+ }
+ /* XXX handling for simplex devices in case of M/BCAST ?? */
+ if (m->m_flags & (M_BCAST | M_MCAST))
+ etype = htons(ETHERTYPE_MPLS_MCAST);
+ else
+ etype = htons(ETHERTYPE_MPLS);
+ break;
+#endif /* MPLS */
case pseudo_AF_HDRCMPLT:
hdrcmplt = 1;
eh = (struct ether_header *)dst->sa_data;
@@ -681,6 +712,13 @@ decapsulate:
schednetisr(NETISR_PPPOE);
break;
#endif /* NPPPOE > 0 */
+#ifdef MPLS
+ case ETHERTYPE_MPLS:
+ case ETHERTYPE_MPLS_MCAST:
+ inq = &mplsintrq;
+ schednetisr(NETISR_MPLS);
+ break;
+#endif
default:
if (llcfound || etype > ETHERMTU)
goto dropanyway;