Index: distrib/sets/lists/base/mi
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/base/mi,v
retrieving revision 1.847
diff -u -p -r1.847 mi
--- distrib/sets/lists/base/mi	5 Dec 2009 20:11:01 -0000	1.847
+++ distrib/sets/lists/base/mi	17 Dec 2009 11:14:51 -0000
@@ -778,6 +778,7 @@
 ./usr/include/netisdn				base-c-usr
 ./usr/include/netiso				base-c-usr
 ./usr/include/netkey				base-c-usr
+./usr/include/netmpls				base-c-usr
 ./usr/include/netnatm				base-c-usr
 ./usr/include/netns				base-obsolete		obsolete
 ./usr/include/netsmb				base-c-usr
@@ -1117,6 +1118,7 @@
 ./usr/sbin/ktutil				base-krb5-bin		kerberos
 ./usr/sbin/kvm_mkdb				base-obsolete		obsolete
 ./usr/sbin/lastlogin				base-sysutil-bin
+./usr/sbin/ldpd					base-router-bin
 ./usr/sbin/link					base-sysutil-bin
 ./usr/sbin/linkfarm				base-obsolete		obsolete
 ./usr/sbin/lmcconfig				base-netutil-bin
Index: distrib/sets/lists/comp/mi
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/comp/mi,v
retrieving revision 1.1344
diff -u -p -r1.1344 mi
--- distrib/sets/lists/comp/mi	5 Dec 2009 22:43:34 -0000	1.1344
+++ distrib/sets/lists/comp/mi	17 Dec 2009 11:14:59 -0000
@@ -1617,6 +1617,7 @@
 ./usr/include/netiso/tp_user.h			comp-c-include
 ./usr/include/netiso/tp_var.h			comp-c-include
 ./usr/include/netiso/tuba_table.h		comp-obsolete		obsolete
+./usr/include/netmpls/mpls.h			comp-c-include
 ./usr/include/netkey/key.h			comp-c-include
 ./usr/include/netkey/key_debug.h		comp-c-include
 ./usr/include/netkey/key_var.h			comp-c-include
Index: distrib/sets/lists/etc/mi
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/etc/mi,v
retrieving revision 1.213
diff -u -p -r1.213 mi
--- distrib/sets/lists/etc/mi	29 Sep 2009 23:56:26 -0000	1.213
+++ distrib/sets/lists/etc/mi	17 Dec 2009 11:14:59 -0000
@@ -212,6 +212,7 @@
 ./etc/rc.d/kdc					etc-krb5-rc
 ./etc/rc.d/kerberos				etc-obsolete		obsolete
 ./etc/rc.d/ldconfig				etc-sys-rc
+./etc/rc.d/ldpd					etc-net-rc
 ./etc/rc.d/lkm1					etc-obsolete		obsolete
 ./etc/rc.d/lkm2					etc-obsolete		obsolete
 ./etc/rc.d/lkm3					etc-obsolete		obsolete
Index: distrib/sets/lists/man/mi
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/man/mi,v
retrieving revision 1.1175
diff -u -p -r1.1175 mi
--- distrib/sets/lists/man/mi	21 Nov 2009 03:24:30 -0000	1.1175
+++ distrib/sets/lists/man/mi	17 Dec 2009 11:15:02 -0000
@@ -2220,6 +2220,7 @@
 ./usr/share/man/cat8/lastlogin.0		man-sysutil-catman	.cat
 ./usr/share/man/cat8/ldconfig.0			man-sysutil-catman	.cat
 ./usr/share/man/cat8/lfs_cleanerd.0		man-sysutil-catman	.cat
+./usr/share/man/cat8/ldpd.0			man-router-catman	.cat
 ./usr/share/man/cat8/link.0			man-sysutil-catman	.cat
 ./usr/share/man/cat8/lmcconfig.0		man-sysutil-catman	.cat
 ./usr/share/man/cat8/lmcctl.0			man-obsolete		obsolete
@@ -4663,6 +4664,7 @@
 ./usr/share/man/html8/ktutil.html		man-krb5-htmlman	kerberos,html
 ./usr/share/man/html8/lastlogin.html		man-sysutil-htmlman	html
 ./usr/share/man/html8/ldconfig.html		man-sysutil-htmlman	html
+./usr/share/man/html8/ldpd.html			man-netutil-htmlman	html
 ./usr/share/man/html8/lfs_cleanerd.html		man-sysutil-htmlman	html
 ./usr/share/man/html8/link.html			man-sysutil-htmlman	html
 ./usr/share/man/html8/lmcconfig.html		man-sysutil-htmlman	html
@@ -7259,6 +7261,7 @@
 ./usr/share/man/man8/kvm_mkdb.8			man-obsolete		obsolete
 ./usr/share/man/man8/lastlogin.8		man-sysutil-man		.man
 ./usr/share/man/man8/ldconfig.8			man-sysutil-man		.man
+./usr/share/man/man8/ldpd.8			man-router-man		.man
 ./usr/share/man/man8/lfs_cleanerd.8		man-sysutil-man		.man
 ./usr/share/man/man8/link.8			man-sysutil-man		.man
 ./usr/share/man/man8/lmcconfig.8		man-sysutil-man		.man
Index: etc/defaults/rc.conf
===================================================================
RCS file: /cvsroot/src/etc/defaults/rc.conf,v
retrieving revision 1.109
diff -u -p -r1.109 rc.conf
--- etc/defaults/rc.conf	1 Oct 2009 16:36:20 -0000	1.109
+++ etc/defaults/rc.conf	17 Dec 2009 11:15:03 -0000
@@ -254,6 +254,10 @@ mrouted=NO		mrouted_flags=""
 route6d=NO		route6d_flags=""
 rtsold=NO		rtsold_flags="-a"	# for ip6mode=autohost only
 
+# Label Distribution Protocol
+#
+ldpd=NO
+
 # Daemons used to boot other hosts over a network.
 #
 rarpd=NO		rarpd_flags="-a"
Index: etc/mtree/NetBSD.dist.base
===================================================================
RCS file: /cvsroot/src/etc/mtree/NetBSD.dist.base,v
retrieving revision 1.8
diff -u -p -r1.8 NetBSD.dist.base
--- etc/mtree/NetBSD.dist.base	5 Dec 2009 20:11:02 -0000	1.8
+++ etc/mtree/NetBSD.dist.base	17 Dec 2009 11:15:04 -0000
@@ -147,6 +147,7 @@
 ./usr/include/netisdn
 ./usr/include/netiso
 ./usr/include/netkey
+./usr/include/netmpls
 ./usr/include/netnatm
 ./usr/include/netsmb
 ./usr/include/nfs
Index: etc/mtree/special
===================================================================
RCS file: /cvsroot/src/etc/mtree/special,v
retrieving revision 1.131
diff -u -p -r1.131 special
--- etc/mtree/special	29 Sep 2009 23:56:27 -0000	1.131
+++ etc/mtree/special	17 Dec 2009 11:15:04 -0000
@@ -222,6 +222,7 @@
 ./etc/rc.d/isdnd		type=file mode=0555
 ./etc/rc.d/kdc			type=file mode=0555
 ./etc/rc.d/ldconfig		type=file mode=0555
+./etc/rc.d/ldpd			type=file mode=0555
 ./etc/rc.d/local		type=file mode=0555
 ./etc/rc.d/lpd			type=file mode=0555
 ./etc/rc.d/lvm			type=file mode=0555
Index: etc/rc.d/Makefile
===================================================================
RCS file: /cvsroot/src/etc/rc.d/Makefile,v
retrieving revision 1.80
diff -u -p -r1.80 Makefile
--- etc/rc.d/Makefile	29 Sep 2009 23:56:27 -0000	1.80
+++ etc/rc.d/Makefile	17 Dec 2009 11:15:04 -0000
@@ -25,7 +25,7 @@ CONFIGFILES=\
 		identd ifwatchd inetd ipfilter ipfs ipmon ipnat ipsec \
 		irdaattach iscsi_target isdnd \
 		kdc \
-		ldconfig local lpd lvm \
+		ldconfig ldpd local lpd lvm \
 		mdnsd mixerctl mopd motd mountall mountcritlocal \
 		mountcritremote mountd moused mrouted \
 		named ndbootd network newsyslog nfsd nfslocking ntpd ntpdate \
Index: sbin/route/keywords.c
===================================================================
RCS file: /cvsroot/src/sbin/route/keywords.c,v
retrieving revision 1.6
diff -u -p -r1.6 keywords.c
--- sbin/route/keywords.c	6 Aug 2006 17:44:56 -0000	1.6
+++ sbin/route/keywords.c	17 Dec 2009 11:15:47 -0000
@@ -36,6 +36,7 @@ struct keytab keywords[] = {
 	{"lockrest", K_LOCKREST},
 	{"mask", K_MASK},
 	{"monitor", K_MONITOR},
+	{"mpls", K_MPLS},
 	{"mtu", K_MTU},
 	{"net", K_NET},
 	{"netmask", K_NETMASK},
@@ -53,6 +54,7 @@ struct keytab keywords[] = {
 	{"show", K_SHOW},
 	{"ssthresh", K_SSTHRESH},
 	{"static", K_STATIC},
+	{"tag", K_TAG},
 	{"x25", K_X25},
 	{"xns", K_XNS},
 	{"xresolve", K_XRESOLVE},
Index: sbin/route/keywords.h
===================================================================
RCS file: /cvsroot/src/sbin/route/keywords.h,v
retrieving revision 1.9
diff -u -p -r1.9 keywords.h
--- sbin/route/keywords.h	6 Aug 2006 17:44:56 -0000	1.9
+++ sbin/route/keywords.h	17 Dec 2009 11:15:47 -0000
@@ -59,3 +59,5 @@ extern struct keytab {
 #define	K_FLUSHALL	49
 #define	K_NOCLONED	50
 #define	K_NOCLONING	51
+#define	K_MPLS		52
+#define	K_TAG		53
Index: sbin/route/route.c
===================================================================
RCS file: /cvsroot/src/sbin/route/route.c,v
retrieving revision 1.119
diff -u -p -r1.119 route.c
--- sbin/route/route.c	28 Dec 2008 20:12:31 -0000	1.119
+++ sbin/route/route.c	17 Dec 2009 11:15:47 -0000
@@ -57,6 +57,7 @@ __RCSID("$NetBSD: route.c,v 1.119 2008/1
 #include <netinet/in.h>
 #include <netatalk/at.h>
 #include <netiso/iso.h>
+#include <netmpls/mpls.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 
@@ -73,6 +74,11 @@ __RCSID("$NetBSD: route.c,v 1.119 2008/1
 #include "keywords.h"
 #include "extern.h"
 
+struct composed_mpls {
+	struct sockaddr_mpls smpls;
+	struct sockaddr_in sinet;
+} __packed__ ;
+
 union sockunion {
 	struct	sockaddr sa;
 	struct	sockaddr_in sin;
@@ -83,13 +89,14 @@ union sockunion {
 	struct	sockaddr_dl sdl;
 #ifndef SMALL
 	struct	sockaddr_iso siso;
+	struct	composed_mpls scmpls;
 #endif /* SMALL */
 };
 
 typedef union sockunion *sup;
 
 struct sou {
-	union sockunion so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp;
+	union sockunion so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp, so_mpls;
 };
 
 static char *any_ntoa(const struct sockaddr *);
@@ -121,7 +128,7 @@ static void sockaddr(const char *, struc
 int	pid, rtm_addrs;
 int	sock;
 int	forcehost, forcenet, doflush, nflag, af, qflag, tflag, Sflag;
-int	iflag, verbose, aflen = sizeof(struct sockaddr_in);
+int	iflag, verbose, aflen = sizeof(struct sockaddr_in), rtag;
 int	locking, lockrest, debugonly, shortoutput;
 struct	rt_metrics rt_metrics;
 u_int32_t  rtm_inits;
@@ -575,6 +582,24 @@ routename(const struct sockaddr *sa, str
 		    ((const struct sockaddr_at *)sa)->sat_addr.s_net,
 		    ((const struct sockaddr_at *)sa)->sat_addr.s_node);
 		break;
+	case AF_MPLS:
+		{
+		const struct sockaddr_in *sin = (const struct sockaddr_in *)
+			(((const struct sockaddr_mpls *)sa) + 1);
+		union mpls_shim ms;
+
+		ms.s_addr =((const struct sockaddr_mpls*)sa)->smpls_addr.s_addr;
+		ms.s_addr = ntohl(ms.s_addr);
+
+		if (sa->sa_len <= sizeof(struct sockaddr_mpls))
+		    snprintf(line, sizeof(line), "%u",
+			ms.shim.label);
+		else
+		    snprintf(line, sizeof(line), "%s:%d",
+			inet_ntoa(sin->sin_addr),
+			ms.shim.label);
+		break;
+		}
 #endif /* SMALL */
 
 	default:
@@ -819,6 +844,17 @@ newroute(int argc, char *const *argv)
 				af = AF_ISO;
 				aflen = sizeof(struct sockaddr_iso);
 				break;
+			case K_MPLS:
+				af = AF_MPLS;
+				/* XXX: Not quite */
+				aflen = sizeof(struct sockaddr_mpls);
+				break;
+			case K_TAG:
+				if (!--argc)
+					usage(1+*argv);
+				aflen = sizeof(struct sockaddr_mpls);
+				(void)getaddr(RTA_MPLS, *++argv, 0, soup);
+				break;
 #endif /* SMALL */
 
 			case K_IFACE:
@@ -1104,7 +1140,7 @@ getaddr(int which, const char *s, struct
 	struct hostent *hp;
 	struct netent *np;
 	u_int32_t val;
-	char *t;
+	char *t, scopy[25];
 	int afamily;  /* local copy of af so we can change it */
 
 	if (af == AF_UNSPEC) {
@@ -1134,6 +1170,10 @@ getaddr(int which, const char *s, struct
 		su = &soup->so_ifa;
 		su->sa.sa_family = af;
 		break;
+	case RTA_MPLS:
+		su = &soup->so_mpls;
+		afamily = AF_MPLS;
+		break;
 	default:
 		su = NULL;
 		usage("Internal Error");
@@ -1239,6 +1279,35 @@ badataddr:
 		su->sat.sat_addr.s_node = val;
 		rtm_addrs |= RTA_NETMASK;
 		return(forcehost || su->sat.sat_addr.s_node != 0);
+	case AF_MPLS:
+		strlcpy(scopy, s, sizeof(scopy));
+		t = strchr (scopy, ':');
+		if (!t) {
+			if (atoi(s) < 0 || atoi(s) >> 20)	/* ETOOMANYATOIS */
+				errx(1, "bad tag: %s", s);
+			su->scmpls.smpls.smpls_addr.s_addr = 0;
+			su->scmpls.smpls.smpls_addr.shim.label = atoi(s);
+			su->scmpls.smpls.smpls_addr.s_addr =
+				htonl(su->scmpls.smpls.smpls_addr.s_addr);
+		} else {
+			*t = '\0';
+			t++;
+			if (atoi(t) < 0 || atoi(t) >> 20)
+				errx(1, "bad label: %s", t);
+			su->scmpls.smpls.smpls_addr.s_addr = 0;
+			su->scmpls.smpls.smpls_family = AF_MPLS;
+			su->scmpls.smpls.smpls_len = sizeof(struct composed_mpls);
+			su->scmpls.smpls.smpls_addr.shim.label = atoi(t);
+			su->scmpls.smpls.smpls_addr.s_addr = htonl(su->scmpls.smpls.smpls_addr.s_addr);
+
+			su->scmpls.sinet.sin_family = AF_INET;
+			su->scmpls.sinet.sin_len = sizeof(struct sockaddr_in);
+			if (inet_aton(scopy, &su->scmpls.sinet.sin_addr) == 0)
+				errx(1, "bad address: %s", scopy);
+		}
+
+		/* We don't have netmasks for tags  */
+		return 1;
 #endif
 
 	case AF_LINK:
@@ -1462,6 +1531,7 @@ rtmsg(int cmd, int flags, struct sou *so
 	NEXTADDR(RTA_GENMASK, soup->so_genmask);
 	NEXTADDR(RTA_IFP, soup->so_ifp);
 	NEXTADDR(RTA_IFA, soup->so_ifa);
+	NEXTADDR(RTA_MPLS, soup->so_mpls);
 	rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
 	if (verbose && ! shortoutput) {
 		if (rtm_addrs)
@@ -1568,7 +1638,7 @@ const char routeflags[] =
 const char ifnetflags[] =
 "\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6NOTRAILERS\7RUNNING\010NOARP\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1\017LINK2\020MULTICAST";
 const char addrnames[] =
-"\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD";
+"\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD\011MPLS";
 
 
 #ifndef SMALL
@@ -1733,7 +1803,7 @@ print_rtmsg(struct rt_msghdr *rtm, int m
 static int
 print_getmsg(struct rt_msghdr *rtm, int msglen, struct sou *soup)
 {
-	struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL, *ifa = NULL;
+	struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL, *ifa = NULL, *mpls = NULL;
 	struct sockaddr_dl *ifp = NULL;
 	struct sockaddr *sa;
 	char *cp;
@@ -1779,6 +1849,9 @@ print_getmsg(struct rt_msghdr *rtm, int 
 				case RTA_IFA:
 					ifa = sa;
 					break;
+				case RTA_MPLS:
+					mpls = sa;
+					break;
 				}
 				ADVANCE(cp, sa);
 			}
@@ -1806,6 +1879,17 @@ print_getmsg(struct rt_msghdr *rtm, int 
 		} else
 			(void)printf("    gateway: %s\n", name);
 	}
+	if (mpls) {
+		const char *name;
+		name = routename(mpls, NULL, RTF_HOST);
+		if(shortoutput) {
+			if (*name == '\0')
+				return 1;
+			printf("%s\n", name);
+		} else
+			printf("   MPLS Tag: %s\n", name);
+	}
+		
 	if (ifa && ! shortoutput)
 		(void)printf(" local addr: %s\n",
 		    routename(ifa, NULL, RTF_HOST));
@@ -1980,6 +2064,14 @@ sodump(sup su, const char *which)
 		(void)printf("%s: iso %s; ",
 		    which, iso_ntoa(&su->siso.siso_addr));
 		break;
+	case AF_MPLS:
+		{
+		union mpls_shim ms;
+		ms.s_addr = ntohl(su->scmpls.smpls.smpls_addr.s_addr);
+		printf("%s: mpls %u; ",
+		    which, ms.shim.label);
+		}
+		break;
 #endif /* SMALL */
 	default:
 		(void)printf("%s: (%d) %s; ",
Index: sbin/route/show.c
===================================================================
RCS file: /cvsroot/src/sbin/route/show.c,v
retrieving revision 1.39
diff -u -p -r1.39 show.c
--- sbin/route/show.c	17 Mar 2009 00:53:42 -0000	1.39
+++ sbin/route/show.c	17 Dec 2009 11:15:47 -0000
@@ -43,11 +43,13 @@ __RCSID("$NetBSD: show.c,v 1.39 2009/03/
 #include <sys/socket.h>
 #include <sys/mbuf.h>
 
+#include <arpa/inet.h>
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <net/route.h>
 #include <netinet/in.h>
+#include <netmpls/mpls.h>
 
 #include <sys/sysctl.h>
 
@@ -138,6 +140,10 @@ parse_show_opts(int argc, char * const *
 			af = AF_ISO;
 			afname = argv[argc - 1] + 1;
 			break;
+		case K_MPLS:
+			af = AF_MPLS;
+			afname = argv[argc - 1] + 1;
+			break;
 #endif /* SMALL */
 		case K_LINK:
 			if (nolink)
@@ -319,6 +325,9 @@ pr_family(int af)
 	case AF_ISO:
 		afname = "ISO";
 		break;
+	case AF_MPLS:
+		afname = "MPLS";
+		break;
 #endif /* SMALL */
 	case AF_APPLETALK:
 		afname = "AppleTalk";
@@ -363,6 +372,26 @@ p_sockaddr(struct sockaddr *sa, struct s
 #endif /* INET6 */
 
 #ifndef SMALL
+	case AF_MPLS:
+		{
+		struct sockaddr_mpls *smpls = (struct sockaddr_mpls *)sa;
+		struct sockaddr_in *sin = (struct sockaddr_in *)(smpls + 1);
+		union mpls_shim ms;
+
+		ms.s_addr = ntohl(smpls->smpls_addr.s_addr);
+
+		if (sa->sa_len <= sizeof(struct sockaddr_mpls) ||
+		    sin->sin_family != AF_INET)
+			snprintf(workbuf, sizeof(workbuf), "%u",
+			ms.shim.label);
+		else
+		    snprintf(workbuf, sizeof(workbuf), "%s:%u",
+			inet_ntoa(sin->sin_addr),
+			ms.shim.label);
+		cp = workbuf;
+		}
+		break;
+
 #endif /* SMALL */
 
 	default:
Index: sys/Makefile
===================================================================
RCS file: /cvsroot/src/sys/Makefile,v
retrieving revision 1.75
diff -u -p -r1.75 Makefile
--- sys/Makefile	30 Dec 2008 22:18:11 -0000	1.75
+++ sys/Makefile	17 Dec 2009 11:15:51 -0000
@@ -2,7 +2,7 @@
 
 SUBDIR=	altq arch compat dev fs miscfs \
 	net net80211 netatalk netbt netipsec netinet netinet6 \
-        netisdn netiso netkey netnatm netsmb \
+        netisdn netiso netkey netmpls netnatm netsmb \
 	nfs opencrypto sys ufs uvm
 
 # interrupt implementation depends on the kernel within the port
Index: sys/arch/amd64/conf/GENERIC
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/conf/GENERIC,v
retrieving revision 1.259
diff -u -p -r1.259 GENERIC
--- sys/arch/amd64/conf/GENERIC	5 Dec 2009 20:11:03 -0000	1.259
+++ sys/arch/amd64/conf/GENERIC	17 Dec 2009 11:15:51 -0000
@@ -175,6 +175,8 @@ options 	INET6		# IPV6
 #options 	IPSEC_ESP	# IP security (encryption part; define w/IPSEC)
 #options 	IPSEC_NAT_T	# IPsec NAT traversal (NAT-T)
 #options 	IPSEC_DEBUG	# debug for IP security
+#options 	MPLS		# MultiProtocol Label Switching
+#options	MPLS_DEBUG	# debug for MPLS
 #options 	MROUTING	# IP multicast routing
 #options 	PIM		# Protocol Independent Multicast
 #options 	ISO,TPIP	# OSI
Index: sys/arch/arc/conf/GENERIC
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/conf/GENERIC,v
retrieving revision 1.162
diff -u -p -r1.162 GENERIC
--- sys/arch/arc/conf/GENERIC	5 Dec 2009 20:11:03 -0000	1.162
+++ sys/arch/arc/conf/GENERIC	17 Dec 2009 11:15:52 -0000
@@ -136,6 +136,7 @@ options 	INET6		# IPV6
 #options 	IPSEC_ESP	# IP security (encryption part; define w/IPSEC)
 #options 	IPSEC_NAT_T	# IPsec NAT traversal (NAT-T)
 #options 	IPSEC_DEBUG	# debug for IP security
+options		MPLS		# MultiProtocol Label Switching
 #options 	MROUTING	# IP multicast routing
 #options 	PIM		# Protocol Independent Multicast
 #options 	ISO,TPIP	# OSI networking
Index: sys/arch/evbmips/conf/MALTA
===================================================================
RCS file: /cvsroot/src/sys/arch/evbmips/conf/MALTA,v
retrieving revision 1.53
diff -u -p -r1.53 MALTA
--- sys/arch/evbmips/conf/MALTA	5 Dec 2009 20:11:11 -0000	1.53
+++ sys/arch/evbmips/conf/MALTA	17 Dec 2009 11:15:52 -0000
@@ -91,6 +91,7 @@ options 	INET		# Internet protocols
 #options 	IPSEC_ESP	# IP security (encryption part; define w/IPSEC)
 #options 	IPSEC_NAT_T	# IPsec NAT traversal (NAT-T)
 #options 	IPSEC_DEBUG	# debug for IP security
+options		MPLS		# MultiProtocol Label Switching
 #options 	MROUTING	# packet forwarding of multicast packets
 #options 	PIM		# Protocol Independent Multicast
 #options 	ISO,TPIP	# OSI networking
Index: sys/arch/i386/conf/ALL
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/conf/ALL,v
retrieving revision 1.222
diff -u -p -r1.222 ALL
--- sys/arch/i386/conf/ALL	5 Dec 2009 20:11:15 -0000	1.222
+++ sys/arch/i386/conf/ALL	17 Dec 2009 11:15:53 -0000
@@ -218,6 +218,7 @@ options 	IPSEC		# IP security
 options 	IPSEC_ESP	# IP security (encryption part; define w/IPSEC)
 options 	IPSEC_NAT_T	# IPsec NAT traversal (NAT-T)
 #options 	IPSEC_DEBUG	# debug for IP security
+options		MPLS		# MultiProtocol Label Switching
 options 	MROUTING	# IP multicast routing
 options 	PIM		# Protocol Independent Multicast
 options 	ISO,TPIP	# OSI
Index: sys/arch/i386/conf/GENERIC
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/conf/GENERIC,v
retrieving revision 1.954
diff -u -p -r1.954 GENERIC
--- sys/arch/i386/conf/GENERIC	5 Dec 2009 20:11:15 -0000	1.954
+++ sys/arch/i386/conf/GENERIC	17 Dec 2009 11:15:54 -0000
@@ -213,6 +213,7 @@ options 	INET6		# IPV6
 #options 	IPSEC_ESP	# IP security (encryption part; define w/IPSEC)
 #options 	IPSEC_NAT_T	# IPsec NAT traversal (NAT-T)
 #options 	IPSEC_DEBUG	# debug for IP security
+#options 	MPLS		# MultiProtocol Label Switching
 #options 	MROUTING	# IP multicast routing
 #options 	PIM		# Protocol Independent Multicast
 #options 	ISO,TPIP	# OSI
Index: sys/conf/files
===================================================================
RCS file: /cvsroot/src/sys/conf/files,v
retrieving revision 1.967
diff -u -p -r1.967 files
--- sys/conf/files	5 Dec 2009 20:11:17 -0000	1.967
+++ sys/conf/files	17 Dec 2009 11:15:57 -0000
@@ -187,6 +187,7 @@ include "netipsec/files.netipsec"
 include "netiso/files.netiso"
 include "netnatm/files.netnatm"
 include "netsmb/files.netsmb"
+include "netmpls/files.netmpls"
 include "net/files.pf"
 
 obsolete defflag		CCITT		# obsolete
Index: sys/dev/ic/ug.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/ug.c,v
retrieving revision 1.11
diff -u -p -r1.11 ug.c
--- sys/dev/ic/ug.c	26 Mar 2008 16:09:37 -0000	1.11
+++ sys/dev/ic/ug.c	17 Dec 2009 11:15:58 -0000
@@ -542,6 +542,9 @@ ug2_attach(device_t dv)
 		aprint_error_dev(dv, "unable to register with sysmon\n");
 		sysmon_envsys_destroy(sc->sc_sme);
 	}
+
+	if (!pmf_device_register(dv, NULL, NULL))
+		aprint_error_dev(dv, "Unable to register with PMF\n");
 }
 
 void
Index: sys/net/if_ethersubr.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_ethersubr.c,v
retrieving revision 1.175
diff -u -p -r1.175 if_ethersubr.c
--- sys/net/if_ethersubr.c	28 Nov 2009 09:20:37 -0000	1.175
+++ sys/net/if_ethersubr.c	17 Dec 2009 11:16:00 -0000
@@ -68,6 +68,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_ethersubr
 #include "opt_iso.h"
 #include "opt_ipx.h"
 #include "opt_mbuftrace.h"
+#include "opt_mpls.h"
 #include "opt_gateway.h"
 #include "opt_pfil_hooks.h"
 #include "opt_pppoe.h"
@@ -181,6 +182,11 @@ extern u_char	at_org_code[3];
 extern u_char	aarp_org_code[3];
 #endif /* NETATALK */
 
+#ifdef MPLS
+#include <netmpls/mpls.h>
+#include <netmpls/mpls_var.h>
+#endif /* MPLS */
+
 static struct timeval bigpktppslim_last;
 static int bigpktppslim = 2;	/* XXX */
 static int bigpktpps_count;
@@ -255,7 +261,12 @@ ether_output(struct ifnet *ifp0, struct 
 			} else
 				senderr(EHOSTUNREACH);
 		}
-		if ((rt->rt_flags & RTF_GATEWAY) && dst->sa_family != AF_NS) {
+		if ((rt->rt_flags & RTF_GATEWAY) && dst->sa_family != AF_NS
+#ifdef MPLS
+		    && dst->sa_family != AF_MPLS) {
+#else
+		    ) {
+#endif
 			if (rt->rt_gwroute == NULL)
 				goto lookup;
 			if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
@@ -428,6 +439,51 @@ ether_output(struct ifnet *ifp0, struct 
 		} break;
 #endif /* ISO */
 
+#ifdef MPLS
+		case AF_MPLS:
+		{
+			const struct sockaddr *wsa = dst;
+			const struct sockaddr_mpls *bsa = (const struct sockaddr_mpls *)dst;
+			size_t wlen = sizeof(struct sockaddr_mpls);
+
+			for (; wlen < dst->sa_len; wlen += wsa->sa_len)
+				wsa = (const struct sockaddr *)
+				    ((const char *)wsa + wsa->sa_len);
+
+			switch (wsa->sa_family) {
+			    case AF_INET:
+				if (!arpresolve(ifp, 0, m, wsa, edst))
+					return 0;	/* Not yet resolved */
+				break;
+			    default:
+				senderr(EHOSTUNREACH);
+			}
+
+			etype = htons(ETHERTYPE_MPLS);
+
+			if (bsa->smpls_addr.shim.label == MPLS_LABEL_IMPLNULL) {
+				/*
+				 * We have to POP label. I don't use
+				 * IP queue and prefer this way
+				 * because IP routing may give us a
+				 * different result.
+				 */
+				switch(wsa->sa_family) {
+				    case AF_INET:
+					etype = htons(ETHERTYPE_IP);
+					break;
+				    case AF_INET6:
+					etype = htons(ETHERTYPE_IPV6);
+					break;
+				    default:
+					goto bad;
+				}
+				m_adj(m, sizeof(union mpls_shim)); /* XXX: adj until bos */
+			}
+		}
+		break;
+#endif /* MPLS */
+
 	case pseudo_AF_HDRCMPLT:
 		hdrcmplt = 1;
 		memcpy(esrc,
@@ -456,6 +512,21 @@ ether_output(struct ifnet *ifp0, struct 
 	 */
 	if (etype == 0)
 		etype = htons(m->m_pkthdr.len);
+#ifdef MPLS
+	/* Prepend mpls shim */
+	if (rt0 && rt0->rt_mpls) {
+		switch(dst->sa_family) {
+		    case AF_INET:
+			m = mpls_label_inet(m, rt0->rt_mpls);
+			etype = htons(ETHERTYPE_MPLS);
+			break;
+		    case AF_INET6:
+			m = mpls_label_inet6(m, rt0->rt_mpls);
+			etype = htons(ETHERTYPE_MPLS);
+			break;
+		}
+	}
+#endif /* MPLS */
 	/*
 	 * Add local net header.  If no space in first mbuf,
 	 * allocate another.
@@ -510,7 +581,6 @@ ether_output(struct ifnet *ifp0, struct 
 	if (ALTQ_IS_ENABLED(&ifp->if_snd))
 		altq_etherclassify(&ifp->if_snd, m, &pktattr);
 #endif
-
 	return ifq_enqueue(ifp, m ALTQ_COMMA ALTQ_DECL(&pktattr));
 
 bad:
@@ -642,6 +712,9 @@ ether_input(struct ifnet *ifp, struct mb
 	/*
 	 * Determine if the packet is within its size limits.
 	 */
+#ifdef MPLS
+	if (etype != ETHERTYPE_MPLS)
+#endif
 	if (m->m_pkthdr.len >
 	    ETHER_MAX_FRAME(ifp, etype, m->m_flags & M_HASFCS)) {
 		if (ppsratecheck(&bigpktppslim_last, &bigpktpps_count,
@@ -907,6 +980,12 @@ ether_input(struct ifnet *ifp, struct mb
 			aarpinput(ifp, m); /* XXX */
 			return;
 #endif /* NETATALK */
+#ifdef MPLS
+		case ETHERTYPE_MPLS:
+			schednetisr(NETISR_MPLS);
+			inq = &mplsintrq;
+			break;
+#endif	/* MPLS */
 		default:
 			m_freem(m);
 			return;
Index: sys/net/if_gre.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_gre.c,v
retrieving revision 1.141
diff -u -p -r1.141 if_gre.c
--- sys/net/if_gre.c	2 Sep 2009 14:56:57 -0000	1.141
+++ sys/net/if_gre.c	17 Dec 2009 11:16:00 -0000
@@ -50,6 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1
 #include "opt_atalk.h"
 #include "opt_gre.h"
 #include "opt_inet.h"
+#include "opt_mpls.h"
 #include "bpfilter.h"
 
 #include <sys/param.h>
@@ -102,6 +103,11 @@ __KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1
 #include <netatalk/at_extern.h>
 #endif
 
+#ifdef MPLS
+#include <netmpls/mpls.h>
+#include <netmpls/mpls_var.h>
+#endif
+
 #if NBPFILTER > 0
 #include <sys/time.h>
 #include <net/bpf.h>
@@ -905,7 +911,16 @@ gre_input(struct gre_softc *sc, struct m
 		isr = NETISR_IPV6;
 		af = AF_INET6;
 		break;
-#endif
+#endif	/* INET6 */
+
+#ifdef MPLS
+	case ETHERTYPE_MPLS:
+	case ETHERTYPE_MPLS_MCAST:
+		ifq = &mplsintrq;
+		isr = NETISR_MPLS;
+		af = AF_MPLS;
+		break;
+#endif	/* MPLS */
 	default:	   /* others not yet supported */
 		GRE_DPRINTF(sc, "unhandled ethertype 0x%04x\n",
 		    ntohs(gh->ptype));
@@ -974,6 +989,13 @@ gre_output(struct ifnet *ifp, struct mbu
 		/* TBD Extract the IP ToS field and set the
 		 * encapsulating protocol's ToS to suit.
 		 */
+#ifdef MPLS
+		if (rt->rt_mpls != NULL) {
+			etype = htons(ETHERTYPE_MPLS);
+			m = mpls_label_inet(m, rt->rt_mpls);
+			break;
+		}
+#endif
 		etype = htons(ETHERTYPE_IP);
 		break;
 #endif
@@ -984,9 +1006,21 @@ gre_output(struct ifnet *ifp, struct mbu
 #endif
 #ifdef INET6
 	case AF_INET6:
+#ifdef MPLS
+		if (rt->rt_mpls != NULL) {
+			etype = htons(ETHERTYPE_MPLS);
+			m = mpls_label_inet6(m, rt->rt_mpls);
+			break;
+		}
+#endif
 		etype = htons(ETHERTYPE_IPV6);
 		break;
 #endif
+#ifdef MPLS
+	case AF_MPLS:
+		etype = htons(ETHERTYPE_MPLS);
+		break;
+#endif
 	default:
 		IF_DROP(&ifp->if_snd);
 		m_freem(m);
Index: sys/net/netisr.h
===================================================================
RCS file: /cvsroot/src/sys/net/netisr.h,v
retrieving revision 1.39
diff -u -p -r1.39 netisr.h
--- sys/net/netisr.h	12 Nov 2008 12:36:28 -0000	1.39
+++ sys/net/netisr.h	17 Dec 2009 11:16:00 -0000
@@ -52,6 +52,7 @@
 #include "opt_inet.h"
 #include "opt_atalk.h"
 #include "opt_iso.h"
+#include "opt_mpls.h"
 #include "opt_natm.h"
 #include "arp.h"
 #endif /* defined(_KERNEL_OPT) */
@@ -91,6 +92,10 @@
 #ifdef NETATALK
 #include <netatalk/at_extern.h>
 #endif
+#ifdef MPLS
+#include <netmpls/mpls.h>
+#include <netmpls/mpls_var.h>
+#endif
 
 #endif /* !defined(_LOCORE) */
 #endif /* defined(_KERNEL) */
@@ -112,6 +117,7 @@
 #define	NETISR_ISDN	26		/* same as AF_E164 */
 #define	NETISR_NATM	27		/* same as AF_NATM */
 #define	NETISR_ARP	28		/* same as AF_ARP */
+#define	NETISR_MPLS	33		/* same as AF_MPLS */
 #define	NETISR_MAX	AF_MAX
 
 #if !defined(_LOCORE) && defined(_KERNEL)
Index: sys/net/netisr_dispatch.h
===================================================================
RCS file: /cvsroot/src/sys/net/netisr_dispatch.h,v
retrieving revision 1.14
diff -u -p -r1.14 netisr_dispatch.h
--- sys/net/netisr_dispatch.h	14 Jul 2007 21:02:42 -0000	1.14
+++ sys/net/netisr_dispatch.h	17 Dec 2009 11:16:00 -0000
@@ -45,5 +45,8 @@
 #ifdef NATM
 	DONETISR(NETISR_NATM,natmintr);
 #endif
+#ifdef MPLS
+	DONETISR(NETISR_MPLS,mplsintr);
+#endif
 
 #endif /* !_NET_NETISR_DISPATCH_H_ */
Index: sys/net/route.c
===================================================================
RCS file: /cvsroot/src/sys/net/route.c,v
retrieving revision 1.121
diff -u -p -r1.121 route.c
--- sys/net/route.c	3 Nov 2009 00:30:11 -0000	1.121
+++ sys/net/route.c	17 Dec 2009 11:16:00 -0000
@@ -118,6 +118,8 @@ __KERNEL_RCSID(0, "$NetBSD: route.c,v 1.
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 
+#include <netmpls/mpls.h>
+
 #ifdef RTFLUSH_DEBUG
 #define	rtcache_debug() __predict_false(_rtcache_debug)
 #else /* RTFLUSH_DEBUG */
@@ -373,6 +375,7 @@ rtalloc1(const struct sockaddr *dst, int
 				    rt->rt_ifp->if_dl->ifa_addr;
 				info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
 			}
+			info.rti_info[RTAX_MPLS] = (struct sockaddr *)rt->rt_mpls;
 			rt_missmsg(RTM_ADD, &info, rt->rt_flags, 0);
 		} else
 			rt->rt_refcnt++;
@@ -495,6 +498,7 @@ rtredirect(const struct sockaddr *dst, c
 			info.rti_info[RTAX_NETMASK] = netmask;
 			info.rti_ifa = ifa;
 			info.rti_flags = flags;
+			info.rti_info[RTAX_MPLS] = NULL;
 			rt = NULL;
 			error = rtrequest1(RTM_ADD, &info, &rt);
 			if (rt != NULL)
@@ -737,6 +741,7 @@ rtrequest1(int req, struct rt_addrinfo *
 			RTFREE(rt->rt_gwroute);
 			rt->rt_gwroute = NULL;
 		}
+		rt_setmpls(rt, NULL);
 		if (rt->rt_parent) {
 			rt->rt_parent->rt_refcnt--;
 			rt->rt_parent = NULL;
@@ -805,6 +810,7 @@ rtrequest1(int req, struct rt_addrinfo *
 		rt_set_ifa(rt, ifa);
 		RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
 		rt->rt_ifp = ifa->ifa_ifp;
+		rt_setmpls(rt, info->rti_info[RTAX_MPLS]);
 		if (req == RTM_RESOLVE) {
 			rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */
 			rt->rt_parent = *ret_nrt;
@@ -1407,3 +1413,19 @@ rt_walktree(sa_family_t family, int (*f)
 
 	return rn_walktree(rnh, rt_walktree_visitor, &rw);
 }
+
+void
+rt_setmpls(struct rtentry *rt, const struct sockaddr *s)
+{
+	if (rt->rt_mpls != NULL) {
+		sockaddr_free((struct sockaddr *)rt->rt_mpls);
+		rt->rt_mpls = NULL;
+	}
+
+	if (s == NULL)
+		return;
+
+	rt->rt_mpls = (struct sockaddr_mpls*)sockaddr_dup(s, M_NOWAIT);
+
+	KASSERT(rt->rt_mpls != NULL);
+}
Index: sys/net/route.h
===================================================================
RCS file: /cvsroot/src/sys/net/route.h,v
retrieving revision 1.74
diff -u -p -r1.74 route.h
--- sys/net/route.h	3 Nov 2009 00:30:31 -0000	1.74
+++ sys/net/route.h	17 Dec 2009 11:16:01 -0000
@@ -124,6 +124,7 @@ struct rtentry {
 	void *	rt_llinfo;		/* pointer to link level info cache */
 	struct	nrt_metrics rt_rmx;	/* metrics used by rx'ing protocols */
 	struct	rtentry *rt_gwroute;	/* implied entry for gatewayed routes */
+	struct	sockaddr_mpls *rt_mpls;	/* MPLS tag */
 	LIST_HEAD(, rttimer) rt_timer;  /* queue of timeouts for misc funcs */
 	struct	rtentry *rt_parent;	/* parent of cloned route */
 	struct sockaddr *_rt_key;
@@ -243,6 +244,7 @@ struct rt_msghdr {
 #define RTA_IFA		0x20	/* interface addr sockaddr present */
 #define RTA_AUTHOR	0x40	/* sockaddr for author of redirect */
 #define RTA_BRD		0x80	/* for NEWADDR, broadcast or p-p dest addr */
+#define	RTA_MPLS	0x100	/* MPLS */
 
 /*
  * Index offsets for sockaddr array for alternate internal encoding.
@@ -255,7 +257,8 @@ struct rt_msghdr {
 #define RTAX_IFA	5	/* interface addr sockaddr present */
 #define RTAX_AUTHOR	6	/* sockaddr for author of redirect */
 #define RTAX_BRD	7	/* for NEWADDR, broadcast or p-p dest addr */
-#define RTAX_MAX	8	/* size of array to allocate */
+#define	RTAX_MPLS	8	/* MPLS */
+#define RTAX_MAX	9	/* size of array to allocate */
 
 #define RT_ROUNDUP(a) \
 	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
@@ -276,6 +279,7 @@ struct route_cb {
 	int	ipx_count;
 	int	ns_count;
 	int	iso_count;
+	int	mpls_count;
 	int	any_count;
 };
 
@@ -349,6 +353,7 @@ void	 rt_maskedcopy(const struct sockadd
 void	 rt_missmsg(int, struct rt_addrinfo *, int, int);
 struct mbuf *rt_msg1(int, struct rt_addrinfo *, void *, int);
 void	 rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *);
+void	 rt_setmpls(struct rtentry *, const struct sockaddr *);
 int	 rt_setgate(struct rtentry *, const struct sockaddr *);
 void	 rt_setmetrics(u_long, const struct rt_metrics *, struct nrt_metrics *);
 int      rt_timer_add(struct rtentry *,
Index: sys/net/rtsock.c
===================================================================
RCS file: /cvsroot/src/sys/net/rtsock.c,v
retrieving revision 1.127
diff -u -p -r1.127 rtsock.c
--- sys/net/rtsock.c	16 Sep 2009 15:23:04 -0000	1.127
+++ sys/net/rtsock.c	17 Dec 2009 11:16:01 -0000
@@ -64,6 +64,7 @@
 __KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.127 2009/09/16 15:23:04 pooka Exp $");
 
 #include "opt_inet.h"
+#include "opt_mpls.h"
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
 #endif
@@ -87,6 +88,10 @@ __KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1
 #include <net/route.h>
 #include <net/raw_cb.h>
 
+#ifdef MPLS
+#include <netmpls/mpls.h>
+#endif
+
 #if defined(COMPAT_14) || defined(COMPAT_50)
 #include <compat/net/if.h>
 #endif
@@ -128,12 +133,17 @@ rt_adjustcount(int af, int cnt)
 	case AF_IPX:
 		route_cb.ipx_count += cnt;
 		return;
-	case AF_NS:
-		route_cb.ns_count += cnt;
-		return;
 	case AF_ISO:
 		route_cb.iso_count += cnt;
 		return;
+#ifdef MPLS
+	case AF_MPLS:
+		route_cb.mpls_count += cnt;
+		return;
+#endif /* MPLS */
+	case AF_NS:
+		route_cb.ns_count += cnt;
+		return;
 	}
 }
 
@@ -339,6 +349,9 @@ route_output(struct mbuf *m, ...)
 			info.rti_info[RTAX_DST] = rt_getkey(rt);
 			info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
 			info.rti_info[RTAX_NETMASK] = rt_mask(rt);
+#ifdef MPLS
+			info.rti_info[RTAX_MPLS] = (struct sockaddr*)rt->rt_mpls;
+#endif
 			if ((rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) == 0)
 				;
 			else if ((ifp = rt->rt_ifp) != NULL) {
@@ -403,6 +416,9 @@ route_output(struct mbuf *m, ...)
 			if (info.rti_info[RTAX_GATEWAY] &&
 			    rt_setgate(rt, info.rti_info[RTAX_GATEWAY]))
 				senderr(EDQUOT);
+#ifdef MPLS
+			rt_setmpls(rt, info.rti_info[RTAX_MPLS]);
+#endif
 			/* new gateway could require new ifaddr, ifp;
 			   flags may also be different; ifp may be specified
 			   by ll sockaddr when protocol address is ambiguous */
Index: sys/netinet/ip_icmp.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_icmp.c,v
retrieving revision 1.122
diff -u -p -r1.122 ip_icmp.c
--- sys/netinet/ip_icmp.c	7 Dec 2009 18:47:24 -0000	1.122
+++ sys/netinet/ip_icmp.c	17 Dec 2009 11:16:01 -0000
@@ -177,8 +177,6 @@ static struct rttimer_queue *icmp_redire
 static void icmp_mtudisc_timeout(struct rtentry *, struct rttimer *);
 static void icmp_redirect_timeout(struct rtentry *, struct rttimer *);
 
-static int icmp_ratelimit(const struct in_addr *, const int, const int);
-
 static void sysctl_netinet_icmp_setup(struct sysctllog **);
 
 void
@@ -1251,7 +1249,7 @@ icmp_redirect_timeout(struct rtentry *rt
  *
  * XXX per-destination/type check necessary?
  */
-static int
+int
 icmp_ratelimit(const struct in_addr *dst, const int type,
     const int code)
 {
Index: sys/netinet/ip_icmp.h
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_icmp.h,v
retrieving revision 1.25
diff -u -p -r1.25 ip_icmp.h
--- sys/netinet/ip_icmp.h	8 Sep 2008 23:36:55 -0000	1.25
+++ sys/netinet/ip_icmp.h	17 Dec 2009 11:16:01 -0000
@@ -184,6 +184,7 @@ void	icmp_send(struct mbuf *, struct mbu
 int	icmp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
 
 void	icmp_mtudisc_callback_register(void (*)(struct in_addr));
+int	icmp_ratelimit(const struct in_addr *, const int, const int);
 #endif
 
 
Index: sys/netinet/ip_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_output.c,v
retrieving revision 1.205
diff -u -p -r1.205 ip_output.c
--- sys/netinet/ip_output.c	17 Jul 2009 22:02:54 -0000	1.205
+++ sys/netinet/ip_output.c	17 Dec 2009 11:16:02 -0000
@@ -97,6 +97,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip_output.c,
 #include "opt_inet.h"
 #include "opt_ipsec.h"
 #include "opt_mrouting.h"
+#include "opt_mpls.h"
 
 #include <sys/param.h>
 #include <sys/malloc.h>
@@ -778,6 +779,12 @@ spd_done:
 	if (IN_NEED_CHECKSUM(ifp, M_CSUM_IPv4)) {
 		m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
 	}
+#ifdef MPLS
+	/* don't let interface compute cksum */
+	if (rt && rt->rt_mpls != NULL)
+		sw_csum = m->m_pkthdr.csum_flags;
+	else
+#endif
 	sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags_tx;
 	/*
 	 * If small enough for mtu of path, or if using TCP segmentation
Index: sys/netinet/udp_usrreq.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.179
diff -u -p -r1.179 udp_usrreq.c
--- sys/netinet/udp_usrreq.c	16 Sep 2009 15:23:05 -0000	1.179
+++ sys/netinet/udp_usrreq.c	17 Dec 2009 11:16:02 -0000
@@ -768,16 +768,24 @@ udp4_realinput(struct sockaddr_in *src, 
 		 * Locate pcb(s) for datagram.
 		 */
 		CIRCLEQ_FOREACH(inph, &udbtable.inpt_queue, inph_queue) {
+			int i;
+#define	inmopts	(inp->inp_moptions)
 			inp = (struct inpcb *)inph;
 			if (inp->inp_af != AF_INET)
 				continue;
-
-			if (inp->inp_lport != *dport)
+			if (inmopts == NULL)
 				continue;
-			if (!in_nullhost(inp->inp_laddr)) {
-				if (!in_hosteq(inp->inp_laddr, *dst4))
-					continue;
+			for (i = 0; i < inmopts->imo_num_memberships; i++) {
+				if (inmopts->imo_membership[i]->inm_ifp ==
+					m->m_pkthdr.rcvif &&
+				    in_hosteq(*dst4,
+					inmopts->imo_membership[i]->inm_addr))
+					    break;
 			}
+			if (i == inmopts->imo_num_memberships)
+				continue;
+			if (inp->inp_lport != *dport)
+				continue;
 			if (!in_nullhost(inp->inp_faddr)) {
 				if (!in_hosteq(inp->inp_faddr, *src4) ||
 				    inp->inp_fport != *sport)
Index: sys/netinet6/ip6_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_output.c,v
retrieving revision 1.139
diff -u -p -r1.139 ip6_output.c
--- sys/netinet6/ip6_output.c	7 May 2009 21:51:47 -0000	1.139
+++ sys/netinet6/ip6_output.c	17 Dec 2009 11:16:03 -0000
@@ -68,6 +68,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_output.c
 #include "opt_inet6.h"
 #include "opt_ipsec.h"
 #include "opt_pfil_hooks.h"
+#include "opt_mpls.h"
 
 #include <sys/param.h>
 #include <sys/malloc.h>
@@ -969,6 +970,11 @@ skip_ipsec2:;
 		ipsec_delaux(m);
 #endif
 
+#ifdef MPLS
+		if (rt != NULL && rt->rt_mpls != NULL)
+			sw_csum = m->m_pkthdr.csum_flags;
+		else
+#endif	/* MPLS */
 		sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags_tx;
 		if ((sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6)) != 0) {
 			if (IN6_NEED_CHECKSUM(ifp,
Index: sys/sys/mbuf.h
===================================================================
RCS file: /cvsroot/src/sys/sys/mbuf.h,v
retrieving revision 1.144
diff -u -p -r1.144 mbuf.h
--- sys/sys/mbuf.h	24 Oct 2008 22:31:40 -0000	1.144
+++ sys/sys/mbuf.h	17 Dec 2009 11:16:03 -0000
@@ -890,6 +890,8 @@ struct	m_tag *m_tag_next(struct mbuf *, 
 						    * loop detection/recovery
 						    */
 
+#define	PACKET_TAG_MPLS				69 /* MPLS */
+
 /*
  * Return the number of bytes in the mbuf chain, m.
  */
Index: sys/sys/socket.h
===================================================================
RCS file: /cvsroot/src/sys/sys/socket.h,v
retrieving revision 1.97
diff -u -p -r1.97 socket.h
--- sys/sys/socket.h	5 Dec 2009 20:11:18 -0000	1.97
+++ sys/sys/socket.h	17 Dec 2009 11:16:03 -0000
@@ -210,8 +210,9 @@ struct	accept_filter_arg {
 #endif
 #define AF_BLUETOOTH	31		/* Bluetooth: HCI, SCO, L2CAP, RFCOMM */
 #define	AF_IEEE80211	32		/* IEEE80211 */
+#define	AF_MPLS		33		/* MPLS */
 
-#define	AF_MAX		33
+#define	AF_MAX		34
 
 /*
  * Structure used by kernel to store most
@@ -300,6 +301,7 @@ struct sockaddr_storage {
 #define PF_KEY 		pseudo_AF_KEY	/* like PF_ROUTE, only for key mgmt */
 #endif
 #define PF_BLUETOOTH	AF_BLUETOOTH
+#define PF_MPLS		AF_MPLS
 
 #define	PF_MAX		AF_MAX
 
@@ -377,6 +379,7 @@ struct sockcred {
 	{ "natm", CTLTYPE_NODE }, \
 	{ "arp", CTLTYPE_NODE }, \
 	{ "key", CTLTYPE_NODE }, \
+	{ "mpls", CTLTYPE_NODE }, \
 }
 
 struct kinfo_pcb {
Index: usr.bin/netstat/Makefile
===================================================================
RCS file: /cvsroot/src/usr.bin/netstat/Makefile,v
retrieving revision 1.29
diff -u -p -r1.29 Makefile
--- usr.bin/netstat/Makefile	14 Sep 2009 10:36:50 -0000	1.29
+++ usr.bin/netstat/Makefile	17 Dec 2009 11:16:05 -0000
@@ -15,6 +15,7 @@ BINMODE=2555
 LDADD=	-lkvm
 DPADD=	${LIBKVM}
 CPPFLAGS+= -DIPSEC
+CPPFLAGS+= -DMPLS
 CPPFLAGS+= -I${NETBSDSRCDIR}/sys/dist/pf
 
 .if (${USE_INET6} != "no")
Index: usr.bin/netstat/main.c
===================================================================
RCS file: /cvsroot/src/usr.bin/netstat/main.c,v
retrieving revision 1.73
diff -u -p -r1.73 main.c
--- usr.bin/netstat/main.c	14 Sep 2009 10:36:51 -0000	1.73
+++ usr.bin/netstat/main.c	17 Dec 2009 11:16:05 -0000
@@ -462,6 +462,10 @@ main(argc, argv)
 				af = AF_ISO;
 			else if (strcmp(optarg, "atalk") == 0)
 				af = AF_APPLETALK;
+#ifdef MPLS
+			else if (strcmp(optarg, "mpls") == 0)
+				af = AF_MPLS;
+#endif
 			else
 				errx(1, "%s: unknown address family",
 				    optarg);
Index: usr.bin/netstat/netstat.h
===================================================================
RCS file: /cvsroot/src/usr.bin/netstat/netstat.h,v
retrieving revision 1.39
diff -u -p -r1.39 netstat.h
--- usr.bin/netstat/netstat.h	14 Sep 2009 10:36:51 -0000	1.39
+++ usr.bin/netstat/netstat.h	17 Dec 2009 11:16:05 -0000
@@ -142,6 +142,10 @@ const char *atalk_print2 __P((const stru
 char	*ns_print __P((struct sockaddr *));
 void	routepr __P((u_long));
 
+#ifdef MPLS
+char	*mpls_ntoa(const struct sockaddr *);
+#endif
+
 void	nsprotopr __P((u_long, const char *));
 void	spp_stats __P((u_long, const char *));
 void	idp_stats __P((u_long, const char *));
Index: usr.bin/netstat/show.c
===================================================================
RCS file: /cvsroot/src/usr.bin/netstat/show.c,v
retrieving revision 1.8
diff -u -p -r1.8 show.c
--- usr.bin/netstat/show.c	13 Sep 2009 02:53:17 -0000	1.8
+++ usr.bin/netstat/show.c	17 Dec 2009 11:16:05 -0000
@@ -45,6 +45,9 @@
 #include <netinet/in.h>
 #include <netinet/if_ether.h>
 #include <arpa/inet.h>
+#ifdef MPLS
+#include <netmpls/mpls.h>
+#endif
 
 #include <err.h>
 #include <errno.h>
@@ -288,6 +291,9 @@ pr_family(int paf)
 	case AF_APPLETALK:
 		afname = "AppleTalk";
 		break;
+	case AF_MPLS:
+		afname = "MPLS";
+		break;
 	default:
 		afname = NULL;
 		break;
@@ -419,6 +425,10 @@ routename(struct sockaddr *sa)
 
 	case AF_LINK:
 		return (link_print(sa));
+#ifdef MPLS
+	case AF_MPLS:
+		return mpls_ntoa(sa);
+#endif
 
 #if 0 /* XXX-elad */
 	case AF_UNSPEC:
@@ -637,6 +647,11 @@ netname(struct sockaddr *sa, struct sock
 #endif
 	case AF_LINK:
 		return (link_print(sa));
+#ifdef MPLS
+	case AF_MPLS:
+		strlcpy(line, "Invalid MPLS Network", sizeof(line));
+		break;
+#endif
 	default:
 		snprintf(line, sizeof(line), "af %d: %s",
 		    sa->sa_family, any_ntoa(sa));
@@ -665,6 +680,32 @@ any_ntoa(const struct sockaddr *sa)
 	return (obuf);
 }
 
+#ifdef MPLS
+char *
+mpls_ntoa(const struct sockaddr *sa)
+{
+	static char obuf[100];
+	const struct sockaddr_mpls *sm;
+	const struct sockaddr_in *si;
+	union mpls_shim ms;
+
+	sm = (const struct sockaddr_mpls*)sa;
+	ms.s_addr = ntohl(sm->smpls_addr.s_addr);
+
+	if (sm->smpls_len > sizeof(struct sockaddr_mpls)) {
+		si = (const struct sockaddr_in*)(sm + 1);
+		snprintf(obuf, sizeof(obuf), "%s:%d",
+		    inet_ntoa(si->sin_addr),
+		    ms.shim.label);
+	} else
+		snprintf(obuf, sizeof(obuf), "%u",
+		     ms.shim.label);
+
+	return obuf;
+}
+
+#endif
+
 char *
 link_print(struct sockaddr *sa)
 {
Index: usr.sbin/Makefile
===================================================================
RCS file: /cvsroot/src/usr.sbin/Makefile,v
retrieving revision 1.243
diff -u -p -r1.243 Makefile
--- usr.sbin/Makefile	11 Oct 2009 08:57:54 -0000	1.243
+++ usr.sbin/Makefile	17 Dec 2009 11:16:06 -0000
@@ -11,7 +11,7 @@ SUBDIR=	ac accton acpitools altq apm apm
 	gpioctl grfconfig grfinfo gspa hdaudioctl hilinfo ifwatchd inetd \
 	installboot \
 	iopctl iostat ipwctl irdaattach isdn iteconfig iwictl\
-	kgmon lastlogin link lmcconfig lockstat lpr mailwrapper makefs \
+	kgmon lastlogin ldpd link lmcconfig lockstat lpr mailwrapper makefs \
 	map-mbone mdconfig memswitch mlxctl mmcformat mopd mountd moused \
 	mrinfo mrouted mscdlabel mtrace \
 	mtree ndbootd ndiscvt netgroup_mkdb nfsd ntp ofctl paxctl pcictl \
Index: usr.sbin/postinstall/postinstall
===================================================================
RCS file: /cvsroot/src/usr.sbin/postinstall/postinstall,v
retrieving revision 1.106
diff -u -p -r1.106 postinstall
--- usr.sbin/postinstall/postinstall	13 Oct 2009 07:47:00 -0000	1.106
+++ usr.sbin/postinstall/postinstall	17 Dec 2009 11:16:08 -0000
@@ -1059,7 +1059,7 @@ do_rc()
 		identd ifwatchd inetd ipfilter ipfs ipmon ipnat ipsec \
 		irdaattach iscsi_target isdnd \
 		kdc \
-		ldconfig local lpd lvm\
+		ldpd ldconfig local lpd lvm\
 		mdnsd mixerctl mopd motd mountall mountcritlocal \
 		mountcritremote mountd moused mrouted \
 		named ndbootd network newsyslog nfsd nfslocking ntpd ntpdate \
