[quagga-dev 11588] Re: [PATCH 1/1] bgpd: implement route-map set as-path prepend last-as

Paul Jakma paul at jakma.org
Mon Oct 20 17:53:06 BST 2014


Hi Timo,

On Tue, 7 Oct 2014, Timo Teras wrote:

> I'm fine either way. This was just the easy way out when writing the
> patch.

Any opinions/objections on if I tweak your last-as patch with the 
attached? (And could you sanity-check it, or even help test? :) ).

Also attached, 1 line docs for 'set as-path prepend ...'.

regards,
-- 
Paul Jakma	paul at jakma.org	@pjakma	Key ID: 64A2FF6A
Fortune:
"Summit meetings tend to be like panda matings.	 The expectations are always
high, and the results usually disappointing."
-- Robert Orben
-------------- next part --------------
commit 8543a7fda91b5e46071d0e7f8e57aa29bcde3418
Author: Paul Jakma <paul at opensourcerouting.org>
Date:   Mon Oct 20 17:35:47 2014 +0100

    bgpd: tweak prior set as-path prepend last-as change to use sep. RM funcs
    
    * For readability, just have a separate set of route-map commands for the
      last-as case. The RM layer already does a string lookup to direct different
      cases to different code, let that do its work.

diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 857781f..9a098b9 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -1222,7 +1222,8 @@ struct route_map_rule_cmd route_set_metric_cmd =
 
 /* For AS path prepend mechanism. */
 static route_map_result_t
-route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
+route_set_aspath_prepend (void *rule, struct prefix *prefix,
+                          route_map_object_t type, void *object)
 {
   struct aspath *aspath;
   struct aspath *new;
@@ -1255,32 +1256,73 @@ route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t
   return RMAP_OKAY;
 }
 
-static void *
-route_set_aspath_prepend_compile (const char *arg)
+/* Set as-path prepend rule structure. */
+struct route_map_rule_cmd route_set_aspath_prepend_cmd = 
 {
-  unsigned int num;
+  "as-path prepend",
+  route_set_aspath_prepend,
+  route_aspath_compile,
+  route_aspath_free,
+};
+
 
-  if (sscanf(arg, "last-as %u", &num) == 1 && num > 0 && num < 10)
-    return (void*)(uintptr_t)num;
+/* `set as-path prepend last-as <1-10>' */
+
+static route_map_result_t
+route_set_aspath_prepend_last_as (void *rule, struct prefix *prefix,
+                                  route_map_object_t type, void *object)
+{
+  struct aspath *new;
+  struct bgp_info *binfo;
+  
+  if (type == RMAP_BGP)
+    {
+      binfo = object;
+    
+      if (binfo->attr->aspath->refcnt)
+	new = aspath_dup (binfo->attr->aspath);
+      else
+	new = binfo->attr->aspath;
+
+      as_t as = aspath_leftmost(new);
+      
+      if (!as)
+        as = binfo->peer->as;
+      
+      new = aspath_add_seq_n (new, as, (uintptr_t) rule);
+      
+      binfo->attr->aspath = new;
+    }
 
-  return route_aspath_compile(arg);
+  return RMAP_OKAY;
 }
 
-static void
-route_set_aspath_prepend_free (void *rule)
+static void *
+route_set_aspath_prepend_last_as_compile (const char *arg)
 {
-  if ((uintptr_t)rule > 10)
-    route_aspath_free(rule);
+  char *endptr = NULL;
+  unsigned long num;
+  
+  num = strtoul (arg, &endptr, 10);
+  
+  if (num == ULONG_MAX || *endptr != '\0')
+    return NULL;
+  if (num == 0 || num > 10)
+    return NULL;
+  
+  return (void*)(uintptr_t) num;
 }
 
+static void
+route_set_aspath_prepend_last_as_free (void *rule) {}
 
-/* Set as-path prepend rule structure. */
-struct route_map_rule_cmd route_set_aspath_prepend_cmd = 
+/* Set as-path prepend last-as rule structure. */
+struct route_map_rule_cmd route_set_aspath_prepend_last_as_cmd = 
 {
-  "as-path prepend",
-  route_set_aspath_prepend,
-  route_set_aspath_prepend_compile,
-  route_set_aspath_prepend_free,
+  "as-path prepend last-as",
+  route_set_aspath_prepend_last_as,
+  route_set_aspath_prepend_last_as_compile,
+  route_set_aspath_prepend_last_as_free,
 };
 
 /* `set as-path exclude ASn' */
@@ -3148,10 +3190,22 @@ DEFUN (set_aspath_prepend,
 {
   int ret;
   char *str;
-
-  str = argv_concat (argv, argc, 0);
-  ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
-  XFREE (MTYPE_TMP, str);
+  
+  if (argc >= 2 && strcmp(argv[0], "last-as") == 0)
+    {
+      /* command matching shouldn't let this happen, but just in case */
+      if (argc > 2)
+        return CMD_WARNING;
+      
+      ret = bgp_route_set_add (vty, vty->index, "as-path prepend last-as",
+                               argv[1]);
+    }
+  else
+    {
+      str = argv_concat (argv, argc, 0);
+      ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
+      XFREE (MTYPE_TMP, str);
+    }
 
   return ret;
 }
@@ -3950,6 +4004,7 @@ bgp_route_map_init (void)
   route_map_install_set (&route_set_weight_cmd);
   route_map_install_set (&route_set_metric_cmd);
   route_map_install_set (&route_set_aspath_prepend_cmd);
+  route_map_install_set (&route_set_aspath_prepend_last_as_cmd);
   route_map_install_set (&route_set_aspath_exclude_cmd);
   route_map_install_set (&route_set_origin_cmd);
   route_map_install_set (&route_set_atomic_aggregate_cmd);
-------------- next part --------------
commit a4cee379a4d57e90b304af76c8ffcc4ce9960764
Author: Paul Jakma <paul at opensourcerouting.org>
Date:   Mon Oct 20 17:49:44 2014 +0100

    doc: Document 'set as-path prepend' and 'set as-path prepend last-as'

diff --git a/doc/bgpd.texi b/doc/bgpd.texi
index 5004cbf..7d92b5e 100644
--- a/doc/bgpd.texi
+++ b/doc/bgpd.texi
@@ -496,7 +496,11 @@ This command defines a new AS path access list.
 @end deffn
 
 @deffn {Route Map} {set as-path prepend @var{as-path}} {}
- at deffnx {Route Map} {set as-path prepend last-as @var{num}} {}
+Prepend the given string of AS numbers to the AS_PATH.
+ at end deffn
+
+ at deffn {Route Map} {set as-path prepend last-as @var{num}} {}
+Prepend the existing last AS number (the leftmost ASN) to the AS_PATH.
 @end deffn
 
 @node Private AS Numbers


More information about the Quagga-dev mailing list