Commit c865cae3 authored by Ondrej Zajicek's avatar Ondrej Zajicek
Browse files

Fixes 'show route export' w.r.t. protocols with different RA_* types.

parent 984d7349
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -498,7 +498,6 @@ r_args:
     if ($$->export_mode) cf_error("Protocol specified twice");
     if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
     $$->export_mode = $2;
     $$->primary_only = 1;
     $$->export_protocol = c->proto;
     $$->running_on_config = c->proto->cf->global;
   }
+61 −34
Original line number Diff line number Diff line
@@ -2246,59 +2246,82 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
{
  rte *e, *ee;
  byte ia[STD_ADDRESS_P_LENGTH+8];
  struct announce_hook *a;
  int ok;
  struct ea_list *tmpa;
  struct announce_hook *a = NULL;
  int first = 1;
  int pass = 0;

  bsprintf(ia, "%I/%d", n->n.prefix, n->n.pxlen);

  if (d->export_mode)
    {
      a = proto_find_announce_hook(d->export_protocol, d->table);
      if (!a)
	return;
    }

  for (e = n->routes; e; e = e->next)
    {
      if (rte_is_filtered(e) != d->filtered)
	continue;

      struct ea_list *tmpa;
      struct rte_src *src = e->attrs->src;
      struct proto *p1 = d->export_protocol;
      struct proto *p2 = d->show_protocol;

      if (ia[0])
	d->net_counter++;
      d->rt_counter++;
      d->net_counter += first;
      first = 0;

      if (pass)
	continue;

      ee = e;
      rte_update_lock();		/* We use the update buffer for filtering */
      tmpa = make_tmp_attrs(e, rte_update_pool);
      ok = f_run(d->filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) <= F_ACCEPT;
      if (p2 && p2 != src->proto) ok = 0;
      if (ok && d->export_mode)

      if (d->export_mode)
	{
	  int ic;
	  if ((ic = p1->import_control ? p1->import_control(p1, &e, &tmpa, rte_update_pool) : 0) < 0)
	    ok = 0;
	  else if (!ic && d->export_mode > 1)
	  struct proto *ep = d->export_protocol;
	  int ic = ep->import_control ? ep->import_control(ep, &e, &tmpa, rte_update_pool) : 0;

	  if (ep->accept_ra_types == RA_OPTIMAL)
	    pass = 1;

	  if (ic < 0)
	    goto skip;

	  if (d->export_mode > 1)
	    {
	      /* FIXME - this shows what should be exported according
		 to current filters, but not what was really exported.
		 'configure soft' command may change the export filter
		 and do not update routes */
	      /*
	       * FIXME - This shows what should be exported according to current
	       * filters, but not what was really exported. 'configure soft'
	       * command may change the export filter and do not update routes.
	       */

	      if (!ic && (f_run(a->out_filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT))
		goto skip;

	      if ((a = proto_find_announce_hook(p1, d->table)) && 
		  (f_run(a->out_filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT))
		ok = 0;
	      if (ep->accept_ra_types == RA_ACCEPTED)
		pass = 1;
	    }
	}
      if (ok)
	{

      if (d->show_protocol && (d->show_protocol != e->attrs->src->proto))
	goto skip;

      if (f_run(d->filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT)
	goto skip;

      d->show_counter++;
      if (d->stats < 2)
	rt_show_rte(c, ia, e, d, tmpa);
      ia[0] = 0;
	}

    skip:
      if (e != ee)
      {
	rte_free(e);
	e = ee;
      }
      rte_update_unlock();

      if (d->primary_only)
	break;
    }
@@ -2360,10 +2383,14 @@ rt_show(struct rt_show_data *d)
  net *n;

  /* Default is either a master table or a table related to a respective protocol */
  if ((!d->table) && d->export_protocol) d->table = d->export_protocol->table;
  if ((!d->table) && d->show_protocol) d->table = d->show_protocol->table;
  if (!d->table && d->export_protocol) d->table = d->export_protocol->table;
  if (!d->table && d->show_protocol) d->table = d->show_protocol->table;
  if (!d->table) d->table = config->master_rtc->table;

  /* Filtered routes are neither exported nor have sensible ordering */
  if (d->filtered && (d->export_mode || d->primary_only))
    cli_msg(0, "");

  if (d->pxlen == 256)
    {
      FIB_ITERATE_INIT(&d->fit, &d->table->fib);