From 7da48a2fc90966fd988d4e0fdfc1c1bcebc3d67e Mon Sep 17 00:00:00 2001 From: Jan Moskyto Matejka Date: Wed, 2 Mar 2016 14:36:38 +0100 Subject: [PATCH] MPLS: Allowing MPLS stack route attribute and setup in static protocol --- conf/confbase.Y | 19 ++++++++++++++++++- lib/Modules | 1 + nest/config.Y | 4 +++- nest/route.h | 1 + nest/rt-attr.c | 14 ++++++++++++++ proto/static/config.Y | 1 + proto/static/static.c | 15 +++++++++++++++ proto/static/static.h | 1 + 8 files changed, 54 insertions(+), 2 deletions(-) diff --git a/conf/confbase.Y b/conf/confbase.Y index 768e4c70..05d3d5f8 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -16,6 +16,7 @@ CF_HDR #include "lib/socket.h" #include "lib/timer.h" #include "lib/string.h" +#include "lib/mpls.h" #include "nest/protocol.h" #include "nest/iface.h" #include "nest/route.h" @@ -44,6 +45,7 @@ CF_DECLS ip6_addr ip6; net_addr net; net_addr *net_ptr; + struct mpls_stack *mpls; struct symbol *s; char *t; struct rtable_config *r; @@ -84,6 +86,7 @@ CF_DECLS %type ipa %type net_ip4_ net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa %type net_ net_any net_vpn4_ net_vpn6_ net_vpn_ net_roa4_ net_roa6_ net_roa_ +%type mpls_stack_start mpls_stack %type text opttext @@ -95,7 +98,7 @@ CF_DECLS %left '!' %nonassoc '.' -CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT, VPN) +CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT, VPN, MPLS) CF_GRAMMAR @@ -287,6 +290,20 @@ net_or_ipa: } ; +/* MPLS stack */ + +mpls_stack_start: MPLS NUM +{ + $$ = cfg_allocz(sizeof(struct mpls_stack)); + $$->len = 1; + $$->label[0] = $2; +}; + +mpls_stack: + mpls_stack_start + | mpls_stack '/' NUM { $1->label[$1->len++] = $3; $$ = $1; } +; + datetime: TEXT { diff --git a/lib/Modules b/lib/Modules index 6b9b4b0f..38b139f2 100644 --- a/lib/Modules +++ b/lib/Modules @@ -16,6 +16,7 @@ lists.h md5.c md5.h mempool.c +mpls.h resource.c resource.h slab.c diff --git a/nest/config.Y b/nest/config.Y index 6bb686c3..48a83075 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -70,7 +70,7 @@ CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERE CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES) CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENERATE) /* ,ROA */ CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION, SORTED) -CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP) +CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, MPLS_STACK, CLASS, DSCP) CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS) CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT, @@ -664,6 +664,8 @@ proto_patt2: CF_ADDTO(dynamic_attr, IGP_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_GEN_IGP_METRIC); }) +CF_ADDTO(dynamic_attr, MPLS_STACK + { $$ = f_new_dynamic_attr(EAF_TYPE_INT_SET, T_CLIST, EA_GEN_MPLS_STACK); }) CF_CODE diff --git a/nest/route.h b/nest/route.h index 22fca331..a1e59504 100644 --- a/nest/route.h +++ b/nest/route.h @@ -431,6 +431,7 @@ typedef struct eattr { #define EA_ID(ea) ((ea) & 0xff) #define EA_GEN_IGP_METRIC EA_CODE(EAP_GENERIC, 0) +#define EA_GEN_MPLS_STACK EA_CODE(EAP_GENERIC, 1) #define EA_CODE_MASK 0xffff #define EA_ALLOW_UNDEF 0x10000 /* ea_find: allow EAF_TYPE_UNDEF */ diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 7d9605c2..7d664d33 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -671,6 +671,20 @@ get_generic_attr(eattr *a, byte **buf, int buflen UNUSED) *buf += bsprintf(*buf, "igp_metric"); return GA_NAME; } + else if (a->id == EA_GEN_MPLS_STACK) + { + *buf += bsprintf(*buf, "mpls"); + struct adata *ad = a->u.ptr; + u32 *z = ad->data; + int len = ad->length / sizeof(u32); + int i; + + *buf += bsprintf(*buf, " %d", z[0]); + for (i = 1; i < len; i++) + *buf += bsprintf(*buf, "/%d", z[i]); + + return GA_FULL; + } return GA_UNKNOWN; } diff --git a/proto/static/config.Y b/proto/static/config.Y index 86359f0b..cd6a0dd2 100644 --- a/proto/static/config.Y +++ b/proto/static/config.Y @@ -115,6 +115,7 @@ stat_route: stat_route_item: cmd { *this_srt_last_cmd = $1; this_srt_last_cmd = &($1->next); } | BFD bool ';' { this_srt->use_bfd = $2; cf_check_bfd($2); } + | mpls_stack ';' { this_srt->mpls_stack = $1; } ; stat_route_opts: diff --git a/proto/static/static.c b/proto/static/static.c index 6239fccb..3dff5240 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -45,6 +45,7 @@ #include "filter/filter.h" #include "lib/string.h" #include "lib/alloca.h" +#include "lib/mpls.h" #include "static.h" @@ -76,6 +77,20 @@ static_install(struct proto *p, struct static_route *r, struct iface *ifa) a.dest = r->dest; a.gw = r->via; a.iface = ifa; + if (r->mpls_stack) { + a.eattrs = lp_alloc(static_lp, sizeof(ea_list) + sizeof(eattr)); + a.eattrs->next = NULL; + a.eattrs->flags = 0; + a.eattrs->count = 1; + a.eattrs->attrs[0].id = EA_GEN_MPLS_STACK; + a.eattrs->attrs[0].flags = 0; + a.eattrs->attrs[0].type = EAF_TYPE_INT_SET; + + struct adata *ad = lp_alloc(static_lp, sizeof(struct adata) + r->mpls_stack->len*sizeof(u32)); + ad->length = r->mpls_stack->len*sizeof(u32); + memcpy(ad->data, r->mpls_stack->label, ad->length); + a.eattrs->attrs[0].u.ptr = ad; + } if (r->dest == RTD_MULTIPATH) { diff --git a/proto/static/static.h b/proto/static/static.h index 51486e83..76e62cd4 100644 --- a/proto/static/static.h +++ b/proto/static/static.h @@ -37,6 +37,7 @@ struct static_route { int installed; /* Installed in rt table, -1 for reinstall */ int use_bfd; /* Configured to use BFD */ int weight; /* Multipath next hop weight */ + struct mpls_stack *mpls_stack; /* MPLS stack to apply to routed packets */ struct bfd_request *bfd_req; /* BFD request, if BFD is used */ };