]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
MPLS: Allowing MPLS stack route attribute and setup in static protocol
authorJan Moskyto Matejka <mq@ucw.cz>
Wed, 2 Mar 2016 13:36:38 +0000 (14:36 +0100)
committerJan Moskyto Matejka <mq@ucw.cz>
Thu, 7 Apr 2016 08:08:43 +0000 (10:08 +0200)
conf/confbase.Y
lib/Modules
nest/config.Y
nest/route.h
nest/rt-attr.c
proto/static/config.Y
proto/static/static.c
proto/static/static.h

index 768e4c7049c02b6e0d430da5215a7f3dd58814bb..05d3d5f8e12e953b04f8e709e421ac64f52c133d 100644 (file)
@@ -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 <a> ipa
 %type <net> net_ip4_ net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa
 %type <net_ptr> net_ net_any net_vpn4_ net_vpn6_ net_vpn_ net_roa4_ net_roa6_ net_roa_
+%type <mpls> mpls_stack_start mpls_stack
 
 %type <t> 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 {
index 6b9b4b0f28eb3a4e280ba9c7185e663eb866fa06..38b139f26be2d9db75a8d0254def6ccb8051db78 100644 (file)
@@ -16,6 +16,7 @@ lists.h
 md5.c
 md5.h
 mempool.c
+mpls.h
 resource.c
 resource.h
 slab.c
index 6bb686c3b0d8e40468c94ee121bde7ef20169a7a..48a830757c4b0c6c16db12d75a77a26c91d04e55 100644 (file)
@@ -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
 
index 22fca331754f5e889a3d47ac337a0eb9d69a34d8..a1e59504c25a006fbf82407a1b26b9a81fecefec 100644 (file)
@@ -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 */
index 7d9605c2632f9b206f00c8db3965a1597dd33c97..7d664d33a58f5f9e7adee4120c6cb7e53d06e160 100644 (file)
@@ -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;
 }
index 86359f0bbd6caa2bbb6ac26e76d5907d235d0af0..cd6a0dd2f3652199afae4c009f5d61cae70c149c 100644 (file)
@@ -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:
index 6239fccbb9bf0a91be72f69332751248c99d25cd..3dff5240bd3de9cace558e8683354a6d11bb1fe1 100644 (file)
@@ -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)
     {
index 51486e836f0feb750408eaab7734ca77156ab418..76e62cd4fc434e81ef7d95df5476086d69d029c7 100644 (file)
@@ -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 */
 };