Hi,

That'd be a neat feature to have.

Something I can't quite figure out is, comparing this to the:

 'bgpd, doc: table-map feature

patch, why is it OK in this patch to attr_dup the attr, but not in the table-map patch?

Also, (in|out)put_modifier seem to take different approaches to managing the lifetime of the attr in this patch?

regards,

Paul

On Fri, 11 Dec 2015, Donald Sharp wrote:

From: Dinesh Dutt <[email protected]>

This patch adds the ability to see the effect of applying a route-map on the routes received or advertised from or to a neighbor. This effect can be seen without actually affecting the current state. If the result seen is what is desired, then the user can actually apply the route-map. Currently, the application acts on route-map in or out and on unsuppress maps.

Signed-off-by: Dinesh G Dutt <[email protected]>
Signed-off-by: Donald Sharp <[email protected]>
---
bgpd/bgp_route.c | 373 ++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 316 insertions(+), 57 deletions(-)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 126dc11..e17396d 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -714,11 +714,12 @@ bgp_cluster_filter (struct peer *peer, struct attr *attr)

static int
bgp_input_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
-                   afi_t afi, safi_t safi)
+                   afi_t afi, safi_t safi, const char *rmap_name)
{
  struct bgp_filter *filter;
  struct bgp_info info;
  route_map_result_t ret;
+  struct route_map *rmap = NULL;

  filter = &peer->filter[afi][safi];

@@ -726,8 +727,18 @@ bgp_input_modifier (struct peer *peer, struct prefix *p, 
struct attr *attr,
  if (peer->weight)
    (bgp_attr_extra_get (attr))->weight = peer->weight;

+  if (rmap_name)
+    {
+      rmap = route_map_lookup_by_name(rmap_name);
+    }
+  else
+    {
+      if (ROUTE_MAP_IN_NAME(filter))
+       rmap = ROUTE_MAP_IN (filter);
+    }
+
  /* Route map apply. */
-  if (ROUTE_MAP_IN_NAME (filter))
+  if (rmap)
    {
      /* Duplicate current value to new strucutre for modification. */
      info.peer = peer;
@@ -736,7 +747,56 @@ bgp_input_modifier (struct peer *peer, struct prefix *p, 
struct attr *attr,
      SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN);

      /* Apply BGP route map to the attribute. */
-      ret = route_map_apply (ROUTE_MAP_IN (filter), p, RMAP_BGP, &info);
+      ret = route_map_apply (rmap, p, RMAP_BGP, &info);
+
+      peer->rmap_type = 0;
+
+      if (ret == RMAP_DENYMATCH)
+       {
+         /* Free newly generated AS path and community by route-map. */
+         bgp_attr_flush (attr);
+         return RMAP_DENY;
+       }
+    }
+  return RMAP_PERMIT;
+}
+
+static int
+bgp_output_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
+                    afi_t afi, safi_t safi, const char *rmap_name)
+{
+  struct bgp_filter *filter;
+  struct bgp_info info;
+  route_map_result_t ret;
+  struct route_map *rmap = NULL;
+
+  filter = &peer->filter[afi][safi];
+
+  /* Apply default weight value. */
+  if (peer->weight)
+    (bgp_attr_extra_get (attr))->weight = peer->weight;
+
+  if (rmap_name)
+    {
+      rmap = route_map_lookup_by_name(rmap_name);
+    }
+  else
+    {
+      if (ROUTE_MAP_OUT_NAME(filter))
+       rmap = ROUTE_MAP_OUT (filter);
+    }
+
+  /* Route map apply. */
+  if (rmap)
+    {
+      /* Duplicate current value to new strucutre for modification. */
+      info.peer = peer;
+      info.attr = attr;
+
+      SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT);
+
+      /* Apply BGP route map to the attribute. */
+      ret = route_map_apply (rmap, p, RMAP_BGP, &info);

      peer->rmap_type = 0;

@@ -2269,7 +2329,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, 
struct attr *attr,
   * NB: new_attr may now contain newly allocated values from route-map "set"
   * commands, so we need bgp_attr_flush in the error paths, until we intern
   * the attr (which takes over the memory references) */
-  if (bgp_input_modifier (peer, p, &new_attr, afi, safi) == RMAP_DENY)
+  if (bgp_input_modifier (peer, p, &new_attr, afi, safi, NULL) == RMAP_DENY)
    {
      reason = "route-map;";
      bgp_attr_flush (&new_attr);
@@ -10292,19 +10352,22 @@ DEFUN (show_ip_bgp_vpnv4_neighbor_prefix_counts,
  return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MPLS_VPN);
}

-
static void
show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
-               int in)
+               int in, char *delim, const char *rmap_name)
{
  struct bgp_table *table;
  struct bgp_adj_in *ain;
  struct bgp_adj_out *adj;
  unsigned long output_count;
+  unsigned long filtered_count;
  struct bgp_node *rn;
  int header1 = 1;
  struct bgp *bgp;
  int header2 = 1;
+  struct attr attr;
+  struct attr_extra extra;
+  int ret;

  bgp = peer->bgp;

@@ -10313,8 +10376,8 @@ show_adj_route (struct vty *vty, struct peer *peer, 
afi_t afi, safi_t safi,

  table = bgp->rib[afi][safi];

-  output_count = 0;
-
+  output_count = filtered_count = 0;
+
  if (! in && CHECK_FLAG (peer->af_sflags[afi][safi],
                          PEER_STATUS_DEFAULT_ORIGINATE))
    {
@@ -10327,6 +10390,7 @@ show_adj_route (struct vty *vty, struct peer *peer, 
afi_t afi, safi_t safi,
      header1 = 0;
    }

+  attr.extra = &extra;
  for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
    if (in)
      {
@@ -10346,9 +10410,16 @@ show_adj_route (struct vty *vty, struct peer *peer, 
afi_t afi, safi_t safi,
                  header2 = 0;
                }
              if (ain->attr)
-               {
-                 route_vty_out_tmp (vty, &rn->p, ain->attr, safi);
-                 output_count++;
+               {
+                 bgp_attr_dup(&attr, ain->attr);
+                 if (bgp_input_modifier(peer, &rn->p, &attr, afi,
+                                        safi, rmap_name) != RMAP_DENY)
+                   {
+                     route_vty_out_tmp (vty, &rn->p, &attr, safi);
+                     output_count++;
+                   }
+                 else
+                   filtered_count++;
                }
            }
      }
@@ -10370,9 +10441,26 @@ show_adj_route (struct vty *vty, struct peer *peer, 
afi_t afi, safi_t safi,
                  header2 = 0;
                }
              if (adj->attr)
-               {
-                 route_vty_out_tmp (vty, &rn->p, adj->attr, safi);
-                 output_count++;
+               {
+                 if (!CHECK_FLAG(peer->af_flags[afi][safi],
+                                 PEER_FLAG_REFLECTOR_CLIENT)
+                     || bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY))
+                   {
+
+                     bgp_attr_dup(&attr, adj->attr);
+                     ret = bgp_output_modifier(peer, &rn->p, &attr, afi,
+                                               safi, rmap_name);
+                   }
+                 else
+                   ret = RMAP_PERMIT;
+
+                 if (ret != RMAP_DENY)
+                   {
+                     route_vty_out_tmp (vty, &rn->p, &attr, safi);
+                     output_count++;
+                   }
+                 else
+                   filtered_count++;
                }
            }
      }

regards,
--
Paul Jakma | [email protected] | @pjakma | Key ID: 0xD86BF79464A2FF6A
Fortune:
What we anticipate seldom occurs; what we least expect generally happens.
-- Bengamin Disraeli

_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to