From 86864ca6914034d75486f676c1f21b077c65184e Mon Sep 17 00:00:00 2001
From: Michele Marchetto <michele@cvs.openbsd.org>
Date: Thu, 8 Jan 2009 12:52:37 +0000
Subject: Reflect MPLS kernel changes.

ok claudio@
---
 sbin/route/route.c     | 26 +++++++++++---------
 sbin/route/show.c      | 65 +++++++++++++++++++++++++++++++++-----------------
 usr.bin/netstat/show.c | 65 +++++++++++++++++++++++++++++++++-----------------
 3 files changed, 101 insertions(+), 55 deletions(-)

diff --git a/sbin/route/route.c b/sbin/route/route.c
index 8c07e72fe2f..a49967cb88b 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: route.c,v 1.123 2008/12/16 16:21:09 sthen Exp $	*/
+/*	$OpenBSD: route.c,v 1.124 2009/01/08 12:52:35 michele Exp $	*/
 /*	$NetBSD: route.c,v 1.16 1996/04/15 18:27:05 cgd Exp $	*/
 
 /*
@@ -71,7 +71,7 @@ union	sockunion {
 	struct sockaddr_dl	sdl;
 	struct sockaddr_rtlabel	rtlabel;
 	struct sockaddr_mpls	smpls;
-} so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp, so_label;
+} so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp, so_label, so_src;
 
 typedef union sockunion *sup;
 pid_t	pid;
@@ -881,18 +881,21 @@ getmplslabel(char *s, int in)
 	const char *errstr;
 	u_int32_t label;
 
-	rtm_addrs |= RTA_DST;
-	su = &so_dst;
-	su->sa.sa_len = aflen;
-	su->sa.sa_family = af;
-
 	label = strtonum(s, 0, 0x000fffff, &errstr);
 	if (errstr)
 		errx(1, "bad label: %s is %s", s, errstr);
-	if (in)
-		su->smpls.smpls_in_label = htonl(label << MPLS_LABEL_OFFSET);
-	else
-		su->smpls.smpls_out_label = htonl(label << MPLS_LABEL_OFFSET);
+	if (in) {
+		rtm_addrs |= RTA_DST;
+		su = &so_dst;
+		su->smpls.smpls_label = htonl(label << MPLS_LABEL_OFFSET);
+	} else {
+		rtm_addrs |= RTA_SRC;
+		su = &so_src;
+		su->smpls.smpls_label = htonl(label << MPLS_LABEL_OFFSET);
+	}
+
+	su->sa.sa_len = aflen;
+	su->sa.sa_family = af;
 }
 
 int
@@ -1053,6 +1056,7 @@ rtmsg(int cmd, int flags, int fmask, u_short prio)
 	NEXTADDR(RTA_IFP, so_ifp);
 	NEXTADDR(RTA_IFA, so_ifa);
 	NEXTADDR(RTA_LABEL, so_label);
+	NEXTADDR(RTA_SRC, so_src);
 	rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
 	if (verbose)
 		print_rtmsg(&rtm, l);
diff --git a/sbin/route/show.c b/sbin/route/show.c
index 016ea584956..e120e253694 100644
--- a/sbin/route/show.c
+++ b/sbin/route/show.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: show.c,v 1.73 2008/12/15 16:14:57 michele Exp $	*/
+/*	$OpenBSD: show.c,v 1.74 2009/01/08 12:52:36 michele Exp $	*/
 /*	$NetBSD: show.c,v 1.1 1996/11/15 18:01:41 gwr Exp $	*/
 
 /*
@@ -60,7 +60,7 @@
 char	*any_ntoa(const struct sockaddr *);
 char	*link_print(struct sockaddr *);
 char	*label_print_op(u_int32_t);
-char	*label_print(struct sockaddr *);
+char	*label_print(struct sockaddr *, struct sockaddr *);
 
 extern int nflag;
 extern int Fflag;
@@ -110,6 +110,7 @@ void	 p_encap(struct sockaddr *, struct sockaddr *, int);
 void	 p_protocol(struct sadb_protocol *, struct sockaddr *, struct
 	     sadb_protocol *, int);
 void	 p_sockaddr(struct sockaddr *, struct sockaddr *, int, int);
+void	 p_sockaddr_mpls(struct sockaddr *, struct sockaddr *, int, int);
 void	 p_flags(int, char *);
 char	*routename4(in_addr_t);
 char	*routename6(struct sockaddr_in6 *);
@@ -298,6 +299,9 @@ p_rtentry(struct rt_msghdr *rtm)
 		return;
 
 	p_sockaddr(sa, mask, rtm->rtm_flags, WID_DST(sa->sa_family));
+	p_sockaddr_mpls(sa, rti_info[RTAX_SRC], rtm->rtm_flags,
+	    WID_DST(sa->sa_family));
+
 	p_sockaddr(rti_info[RTAX_GATEWAY], NULL, RTF_HOST,
 	    WID_GW(sa->sa_family));
 
@@ -516,15 +520,7 @@ p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width)
 		break;
 	    }
 	case AF_MPLS:
-		if (flags & RTF_HOST || mask == NULL)
-			cp = routename(sa);
-		else
-			cp = netname(sa, mask);
-
-		snprintf(cp, MAXHOSTNAMELEN, "%s %s", cp,
-		    label_print_op(flags));
-
-		break;
+		return;
 	default:
 		if ((flags & RTF_HOST) || mask == NULL)
 			cp = routename(sa);
@@ -542,6 +538,28 @@ p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width)
 	}
 }
 
+static char line[MAXHOSTNAMELEN];
+static char domain[MAXHOSTNAMELEN];
+
+void
+p_sockaddr_mpls(struct sockaddr *in, struct sockaddr *out, int flags, int width)
+{
+	char *cp;
+
+	if (in->sa_family != AF_MPLS)
+		return;
+
+	if (flags & MPLS_OP_POP)
+		cp = label_print(in, NULL);
+	else
+		cp = label_print(in, out);
+
+	snprintf(cp, MAXHOSTNAMELEN, "%s %s", cp,
+	    label_print_op(flags));
+
+	printf("%-*s ", width, cp);
+}
+
 void
 p_flags(int f, char *format)
 {
@@ -555,9 +573,6 @@ p_flags(int f, char *format)
 	printf(format, name);
 }
 
-static char line[MAXHOSTNAMELEN];
-static char domain[MAXHOSTNAMELEN];
-
 char *
 routename(struct sockaddr *sa)
 {
@@ -608,7 +623,7 @@ routename(struct sockaddr *sa)
 	case AF_LINK:
 		return (link_print(sa));
 	case AF_MPLS:
-		return (label_print(sa));
+		return (label_print(sa, NULL));
 	case AF_UNSPEC:
 		if (sa->sa_len == sizeof(struct sockaddr_rtlabel)) {
 			static char name[RTLABEL_LEN];
@@ -816,7 +831,7 @@ netname(struct sockaddr *sa, struct sockaddr *mask)
 	case AF_LINK:
 		return (link_print(sa));
 	case AF_MPLS:
-		return (label_print(sa));
+		return (label_print(sa, NULL));
 	default:
 		snprintf(line, sizeof(line), "af %d: %s",
 		    sa->sa_family, any_ntoa(sa));
@@ -881,21 +896,27 @@ label_print_op(u_int32_t type)
 }
 
 char *
-label_print(struct sockaddr *sa)
+label_print(struct sockaddr *in, struct sockaddr *out)
 {
-	struct sockaddr_mpls	*smpls = (struct sockaddr_mpls *)sa;
+	struct sockaddr_mpls	*insmpls = (struct sockaddr_mpls *)in;
+	struct sockaddr_mpls	*outsmpls = (struct sockaddr_mpls *)out;
 	char			 ifname_in[IF_NAMESIZE];
 	char			 ifname_out[IF_NAMESIZE];
 	char			*in_label;
 	char			*out_label;
 
 	if (asprintf(&in_label, "%u",
-	    ntohl(smpls->smpls_in_label) >> MPLS_LABEL_OFFSET) == -1)
+	    ntohl(insmpls->smpls_label) >> MPLS_LABEL_OFFSET) == -1)
 		err(1, NULL);
 
-	if (asprintf(&out_label, "%u",
-	    ntohl(smpls->smpls_out_label) >> MPLS_LABEL_OFFSET) == -1)
-		err(1, NULL);
+	if (outsmpls) {
+		if (asprintf(&out_label, "%u",
+		    ntohl(outsmpls->smpls_label) >> MPLS_LABEL_OFFSET) == -1)
+			err(1, NULL);
+	} else {
+		if (asprintf(&out_label, "-") == -1)
+			err(1, NULL);
+	}
 
 	(void)snprintf(line, sizeof(line), "%-16s %-10s", in_label,
 	    out_label);
diff --git a/usr.bin/netstat/show.c b/usr.bin/netstat/show.c
index b729e7d00b7..6168adb91b1 100644
--- a/usr.bin/netstat/show.c
+++ b/usr.bin/netstat/show.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: show.c,v 1.16 2008/12/15 21:18:37 michele Exp $	*/
+/*	$OpenBSD: show.c,v 1.17 2009/01/08 12:52:36 michele Exp $	*/
 /*	$NetBSD: show.c,v 1.1 1996/11/15 18:01:41 gwr Exp $	*/
 
 /*
@@ -61,7 +61,7 @@
 char	*any_ntoa(const struct sockaddr *);
 char	*link_print(struct sockaddr *);
 char	*label_print_op(u_int32_t);
-char	*label_print(struct sockaddr *);
+char	*label_print(struct sockaddr *, struct sockaddr *);
 
 #define ROUNDUP(a) \
 	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
@@ -105,6 +105,7 @@ void	 p_encap(struct sockaddr *, struct sockaddr *, int);
 void	 p_protocol(struct sadb_protocol *, struct sockaddr *, struct
 	     sadb_protocol *, int);
 void	 p_sockaddr(struct sockaddr *, struct sockaddr *, int, int);
+void	 p_sockaddr_mpls(struct sockaddr *, struct sockaddr *, int, int);
 void	 p_flags(int, char *);
 char	*routename4(in_addr_t);
 char	*routename6(struct sockaddr_in6 *);
@@ -295,6 +296,9 @@ p_rtentry(struct rt_msghdr *rtm)
 		return;
 
 	p_sockaddr(sa, mask, rtm->rtm_flags, WID_DST(sa->sa_family));
+	p_sockaddr_mpls(sa, rti_info[RTAX_SRC], rtm->rtm_flags,
+	    WID_DST(sa->sa_family));
+
 	p_sockaddr(rti_info[RTAX_GATEWAY], NULL, RTF_HOST,
 	    WID_GW(sa->sa_family));
 	p_flags(rtm->rtm_flags, "%-6.6s ");
@@ -524,15 +528,7 @@ p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width)
 		break;
 	    }
 	case AF_MPLS:
-		if (flags & RTF_HOST || mask == NULL)
-			cp = routename(sa);
-		else
-			cp = netname(sa, mask);
-
-		snprintf(cp, MAXHOSTNAMELEN, "%s %s", cp,
-		    label_print_op(flags));
-
-		break;
+		return;
 	default:
 		if ((flags & RTF_HOST) || mask == NULL)
 			cp = routename(sa);
@@ -550,6 +546,28 @@ p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width)
 	}
 }
 
+static char line[MAXHOSTNAMELEN];
+static char domain[MAXHOSTNAMELEN];
+
+void
+p_sockaddr_mpls(struct sockaddr *in, struct sockaddr *out, int flags, int width)
+{
+	char *cp;
+
+	if (in->sa_family != AF_MPLS)
+		return;
+
+	if (flags & MPLS_OP_POP)
+		cp = label_print(in, NULL);
+	else
+		cp = label_print(in, out);
+
+	snprintf(cp, MAXHOSTNAMELEN, "%s %s", cp,
+	    label_print_op(flags));
+
+	printf("%-*s ", width, cp);
+}
+
 void
 p_flags(int f, char *format)
 {
@@ -563,9 +581,6 @@ p_flags(int f, char *format)
 	printf(format, name);
 }
 
-static char line[MAXHOSTNAMELEN];
-static char domain[MAXHOSTNAMELEN];
-
 char *
 routename(struct sockaddr *sa)
 {
@@ -616,7 +631,7 @@ routename(struct sockaddr *sa)
 	case AF_LINK:
 		return (link_print(sa));
 	case AF_MPLS:
-		return (label_print(sa));
+		return (label_print(sa, NULL));
 	case AF_UNSPEC:
 		if (sa->sa_len == sizeof(struct sockaddr_rtlabel)) {
 			static char name[RTLABEL_LEN];
@@ -824,7 +839,7 @@ netname(struct sockaddr *sa, struct sockaddr *mask)
 	case AF_LINK:
 		return (link_print(sa));
 	case AF_MPLS:
-		return (label_print(sa));
+		return (label_print(sa, NULL));
 	default:
 		snprintf(line, sizeof(line), "af %d: %s",
 		    sa->sa_family, any_ntoa(sa));
@@ -889,21 +904,27 @@ label_print_op(u_int32_t type)
 }
 
 char *
-label_print(struct sockaddr *sa)
+label_print(struct sockaddr *in, struct sockaddr *out)
 {
-	struct sockaddr_mpls	*smpls = (struct sockaddr_mpls *)sa;
+	struct sockaddr_mpls	*insmpls = (struct sockaddr_mpls *)in;
+	struct sockaddr_mpls	*outsmpls = (struct sockaddr_mpls *)out;
 	char			 ifname_in[IF_NAMESIZE];
 	char			 ifname_out[IF_NAMESIZE];
 	char			*in_label;
 	char			*out_label;
 
 	if (asprintf(&in_label, "%u",
-	    ntohl(smpls->smpls_in_label) >> MPLS_LABEL_OFFSET) == -1)
+	    ntohl(insmpls->smpls_label) >> MPLS_LABEL_OFFSET) == -1)
 		err(1, NULL);
 
-	if (asprintf(&out_label, "%u",
-	    ntohl(smpls->smpls_out_label) >> MPLS_LABEL_OFFSET) == -1)
-		err(1, NULL);
+	if (outsmpls) {
+		if (asprintf(&out_label, "%u",
+		    ntohl(outsmpls->smpls_label) >> MPLS_LABEL_OFFSET) == -1)
+			err(1, NULL);
+	} else {
+		if (asprintf(&out_label, "-") == -1)
+			err(1, NULL);
+	}
 
 	(void)snprintf(line, sizeof(line), "%-16s %-10s", in_label,
 	    out_label);
-- 
cgit v1.2.3