summaryrefslogtreecommitdiff
path: root/sbin/route
diff options
context:
space:
mode:
authorEsben Norby <norby@cvs.openbsd.org>2008-04-28 11:36:15 +0000
committerEsben Norby <norby@cvs.openbsd.org>2008-04-28 11:36:15 +0000
commitc20623b142ef4b6771fed62c8f702f5cea16eea4 (patch)
tree0b44500261a8b082a5291a5e18c8ef6984957d03 /sbin/route
parent15918ce230720ac64fab6c3ef09934be436240b8 (diff)
It is now possible to enter static MPLS routes into the kernel.
It is still not possible to set the desired opration for an entry. ok claudio@ laurent@ dlg@
Diffstat (limited to 'sbin/route')
-rw-r--r--sbin/route/keywords.h8
-rw-r--r--sbin/route/keywords.sh5
-rw-r--r--sbin/route/route.c64
-rw-r--r--sbin/route/show.c78
4 files changed, 141 insertions, 14 deletions
diff --git a/sbin/route/keywords.h b/sbin/route/keywords.h
index 012bacad320..10adb12a10a 100644
--- a/sbin/route/keywords.h
+++ b/sbin/route/keywords.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: keywords.h,v 1.20 2007/06/04 12:23:43 henning Exp $ */
+/* $OpenBSD: keywords.h,v 1.21 2008/04/28 11:36:14 norby Exp $ */
/* WARNING! This file was generated by keywords.sh */
@@ -27,6 +27,7 @@ enum {
K_INTERFACE,
K_IFA,
K_IFP,
+ K_IN,
K_INET,
K_INET6,
K_JUMBO,
@@ -37,11 +38,13 @@ enum {
K_LOCKREST,
K_MONITOR,
K_MPATH,
+ K_MPLS,
K_MTU,
K_NET,
K_NETMASK,
K_NOJUMBO,
K_NOSTATIC,
+ K_OUT,
K_PREFIXLEN,
K_PROTO1,
K_PROTO2,
@@ -76,6 +79,7 @@ struct keytab keywords[] = {
{ "interface", K_INTERFACE },
{ "ifa", K_IFA },
{ "ifp", K_IFP },
+ { "in", K_IN },
{ "inet", K_INET },
{ "inet6", K_INET6 },
{ "jumbo", K_JUMBO },
@@ -86,11 +90,13 @@ struct keytab keywords[] = {
{ "lockrest", K_LOCKREST },
{ "monitor", K_MONITOR },
{ "mpath", K_MPATH },
+ { "mpls", K_MPLS },
{ "mtu", K_MTU },
{ "net", K_NET },
{ "netmask", K_NETMASK },
{ "nojumbo", K_NOJUMBO },
{ "nostatic", K_NOSTATIC },
+ { "out", K_OUT },
{ "prefixlen", K_PREFIXLEN },
{ "proto1", K_PROTO1 },
{ "proto2", K_PROTO2 },
diff --git a/sbin/route/keywords.sh b/sbin/route/keywords.sh
index 7ed093a9501..69983487fcb 100644
--- a/sbin/route/keywords.sh
+++ b/sbin/route/keywords.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# $OpenBSD: keywords.sh,v 1.19 2007/06/04 12:23:43 henning Exp $
+# $OpenBSD: keywords.sh,v 1.20 2008/04/28 11:36:14 norby Exp $
# $NetBSD: keywords.sh,v 1.2 1996/11/15 18:57:21 gwr Exp $
# @(#)keywords 8.2 (Berkeley) 3/19/94
#
@@ -27,6 +27,7 @@ iface
interface
ifa
ifp
+in
inet
inet6
jumbo
@@ -37,11 +38,13 @@ lock
lockrest
monitor
mpath
+mpls
mtu
net
netmask
nojumbo
nostatic
+out
prefixlen
proto1
proto2
diff --git a/sbin/route/route.c b/sbin/route/route.c
index 00c0a313bb2..4eeadce79b7 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.112 2007/09/25 08:57:47 henning Exp $ */
+/* $OpenBSD: route.c,v 1.113 2008/04/28 11:36:14 norby Exp $ */
/* $NetBSD: route.c,v 1.16 1996/04/15 18:27:05 cgd Exp $ */
/*
@@ -55,6 +55,7 @@
#include <paths.h>
#include <err.h>
#include <net/if_media.h>
+#include <netmpls/mpls.h>
#include "keywords.h"
#include "show.h"
@@ -69,6 +70,7 @@ union sockunion {
struct sockaddr_in6 sin6;
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;
typedef union sockunion *sup;
@@ -99,6 +101,7 @@ void bprintf(FILE *, int, char *);
void mask_addr(union sockunion *, union sockunion *, int);
int inet6_makenetandmask(struct sockaddr_in6 *);
int getaddr(int, char *, struct hostent **);
+void getmplslabel(char *, int);
int rtmsg(int, int, int);
__dead void usage(char *);
void set_metric(char *, int);
@@ -227,6 +230,9 @@ flushroutes(int argc, char **argv)
case K_LINK:
af = AF_LINK;
break;
+ case K_MPLS:
+ af = AF_MPLS;
+ break;
default:
usage(*argv);
/* NOTREACHED */
@@ -367,6 +373,24 @@ newroute(int argc, char **argv)
af = PF_ROUTE;
aflen = sizeof(union sockunion);
break;
+ case K_MPLS:
+ af = AF_MPLS;
+ aflen = sizeof(struct sockaddr_mpls);
+ break;
+ case K_IN:
+ if (!--argc)
+ usage(1+*argv);
+ if (af != AF_MPLS)
+ errx(1, "-in requires -mpls");
+ getmplslabel(*++argv, 1);
+ break;
+ case K_OUT:
+ if (!--argc)
+ usage(1+*argv);
+ if (af != AF_MPLS)
+ errx(1, "-out requires -mpls");
+ getmplslabel(*++argv, 0);
+ break;
case K_IFACE:
case K_INTERFACE:
iflag++;
@@ -584,6 +608,9 @@ show(int argc, char *argv[])
case K_LINK:
af = AF_LINK;
break;
+ case K_MPLS:
+ af = AF_MPLS;
+ break;
case K_ENCAP:
af = PF_KEY;
break;
@@ -771,7 +798,8 @@ getaddr(int which, char *s, struct hostent **hpp)
case AF_LINK:
link_addr(s, &su->sdl);
return (1);
-
+ case AF_MPLS:
+ errx(1, "mpls labels require -in or -out switch");
case PF_ROUTE:
su->sa.sa_len = sizeof(*su);
sockaddr(s, &su->sa);
@@ -817,6 +845,38 @@ getaddr(int which, char *s, struct hostent **hpp)
}
}
+void
+getmplslabel(char *s, int in)
+{
+ sup su = NULL;
+ const char *errstr;
+ char *ifname;
+ u_int32_t label;
+ u_int16_t ifindex = 0;
+
+ rtm_addrs |= RTA_DST;
+ su = &so_dst;
+ su->sa.sa_len = aflen;
+ su->sa.sa_family = af;
+
+ ifname = strchr(s, SCOPE_DELIMITER);
+ if (ifname) {
+ *ifname++ = '\0';
+ ifindex = if_nametoindex(ifname);
+ }
+
+ 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);
+ su->smpls.smpls_in_ifindex = ifindex;
+ } else {
+ su->smpls.smpls_out_label = htonl(label);
+ su->smpls.smpls_out_ifindex = ifindex;
+ }
+}
+
int
prefixlen(char *s)
{
diff --git a/sbin/route/show.c b/sbin/route/show.c
index 4bcdff24736..4a8296659d9 100644
--- a/sbin/route/show.c
+++ b/sbin/route/show.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: show.c,v 1.61 2007/09/05 20:30:21 claudio Exp $ */
+/* $OpenBSD: show.c,v 1.62 2008/04/28 11:36:14 norby Exp $ */
/* $NetBSD: show.c,v 1.1 1996/11/15 18:01:41 gwr Exp $ */
/*
@@ -44,6 +44,7 @@
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/ip_ipsp.h>
+#include <netmpls/mpls.h>
#include <arpa/inet.h>
#include <err.h>
@@ -59,6 +60,8 @@
char *any_ntoa(const struct sockaddr *);
char *link_print(struct sockaddr *);
+char *label_print_op(u_int8_t);
+char *label_print(struct sockaddr *);
extern int nflag;
extern int Fflag;
@@ -211,15 +214,24 @@ p_rttables(int af, u_int tableid)
void
pr_rthdr(int af)
{
- if (af != PF_KEY)
+
+ switch (af) {
+ case PF_KEY:
+ printf("%-18s %-5s %-18s %-5s %-5s %-22s\n",
+ "Source", "Port", "Destination",
+ "Port", "Proto", "SA(Address/Proto/Type/Direction)");
+ break;
+ case PF_MPLS:
+ printf("%-20s %-20s %-6s %-18s %-6.6s %6.6s %8.8s %6.6s %s\n",
+ "In label", "Out label", "Op", "Gateway",
+ "Flags", "Refs", "Use", "Mtu", "Interface");
+ break;
+ default:
printf("%-*.*s %-*.*s %-6.6s %6.6s %8.8s %6.6s %s\n",
WID_DST(af), WID_DST(af), "Destination",
WID_GW(af), WID_GW(af), "Gateway",
"Flags", "Refs", "Use", "Mtu", "Interface");
- else
- printf("%-18s %-5s %-18s %-5s %-5s %-22s\n",
- "Source", "Port", "Destination",
- "Port", "Proto", "SA(Address/Proto/Type/Direction)");
+ }
}
static void
@@ -286,7 +298,7 @@ p_rtentry(struct rt_msghdr *rtm)
void
p_pfkentry(struct sadb_msg *msg)
{
- static int old = 0;
+ static int old = 0;
struct sadb_address *saddr;
struct sadb_protocol *sap, *saft;
struct sockaddr *sa, *mask;
@@ -345,6 +357,9 @@ pr_family(int af)
case PF_KEY:
afname = "Encap";
break;
+ case AF_MPLS:
+ afname = "MPLS";
+ break;
case AF_APPLETALK:
afname = "AppleTalk";
break;
@@ -361,7 +376,7 @@ pr_family(int af)
void
p_encap(struct sockaddr *sa, struct sockaddr *mask, int width)
{
- char *cp;
+ char *cp;
unsigned short port;
if (mask)
@@ -560,7 +575,8 @@ routename(struct sockaddr *sa)
case AF_LINK:
return (link_print(sa));
-
+ case AF_MPLS:
+ return (label_print(sa));
case AF_UNSPEC:
if (sa->sa_len == sizeof(struct sockaddr_rtlabel)) {
static char name[RTLABEL_LEN];
@@ -759,7 +775,6 @@ char *
netname(struct sockaddr *sa, struct sockaddr *mask)
{
switch (sa->sa_family) {
-
case AF_INET:
return netname4(((struct sockaddr_in *)sa)->sin_addr.s_addr,
(struct sockaddr_in *)mask);
@@ -768,6 +783,8 @@ netname(struct sockaddr *sa, struct sockaddr *mask)
(struct sockaddr_in6 *)mask);
case AF_LINK:
return (link_print(sa));
+ case AF_MPLS:
+ return (label_print(sa));
default:
snprintf(line, sizeof(line), "af %d: %s",
sa->sa_family, any_ntoa(sa));
@@ -816,6 +833,47 @@ link_print(struct sockaddr *sa)
}
}
+char *
+label_print_op(u_int8_t type)
+{
+ switch (type) {
+ case MPLS_OP_POP:
+ return ("POP");
+ case MPLS_OP_SWAP:
+ return ("SWAP");
+ case MPLS_OP_PUSH:
+ return ("PUSH");
+ default:
+ return ("?");
+ }
+}
+
+char *
+label_print(struct sockaddr *sa)
+{
+ struct sockaddr_mpls *smpls = (struct sockaddr_mpls *)sa;
+ char ifname_in[IF_NAMESIZE];
+ char ifname_out[IF_NAMESIZE];
+ char *in_label;
+ char *out_label;
+
+ if (asprintf(&in_label, "%u%%%s", ntohl(smpls->smpls_in_label),
+ if_indextoname(smpls->smpls_in_ifindex, ifname_in)) == -1)
+ err(1, NULL);
+
+ if (asprintf(&out_label, "%u%%%s", ntohl(smpls->smpls_out_label),
+ if_indextoname(smpls->smpls_out_ifindex, ifname_out)) == -1)
+ err(1, NULL);
+
+ (void)snprintf(line, sizeof(line), "%-20s %-20s %-6s", in_label,
+ out_label, label_print_op(smpls->smpls_operation));
+
+ free(in_label);
+ free(out_label);
+
+ return (line);
+}
+
void
index_pfk(struct sadb_msg *msg, void **headers)
{