diff options
author | Esben Norby <norby@cvs.openbsd.org> | 2008-04-28 11:36:15 +0000 |
---|---|---|
committer | Esben Norby <norby@cvs.openbsd.org> | 2008-04-28 11:36:15 +0000 |
commit | c20623b142ef4b6771fed62c8f702f5cea16eea4 (patch) | |
tree | 0b44500261a8b082a5291a5e18c8ef6984957d03 /sbin/route | |
parent | 15918ce230720ac64fab6c3ef09934be436240b8 (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.h | 8 | ||||
-rw-r--r-- | sbin/route/keywords.sh | 5 | ||||
-rw-r--r-- | sbin/route/route.c | 64 | ||||
-rw-r--r-- | sbin/route/show.c | 78 |
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) { |