Commit b7d7599c authored by Ondrej Zajicek (work)'s avatar Ondrej Zajicek (work)
Browse files

BGP: implement Adj-RIB-Out

The patch implements optional internal export table to a channel and
hooks it to BGP so it can be used as Adj-RIB-Out. When enabled, all
exported (post-filtered) routes are stored there. An export table can be
examined using e.g. 'show route export table bgp1.ipv4'.
parent dfe63ed8
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -2705,6 +2705,16 @@ be used in explicit configuration.
	be examined later by <cf/show route/, and can be used to reconfigure
	import filters without full route refresh. Default: off.

	<tag><label id="bgp-export-table">export table <m/switch/</tag>
	A BGP export table contains all routes sent to given BGP neighbor, after
	application of export filters. It is also called <em/Adj-RIB-Out/ in BGP
	terminology. BIRD BGP by default operates without export tables, in
	which case routes from master table are just processed by export filters
	and then announced by BGP. Enabling <cf/export table/ allows to store
	routes after export filter processing, so they can be examined later by
	<cf/show route/, and can be used to eliminate unnecessary updates or
	withdraws. Default: off.

	<tag><label id="bgp-secondary">secondary <m/switch/</tag>
	Usually, if an export filter rejects a selected route, no other route is
	propagated for that network. This option allows to try the next route in
+11 −0
Original line number Diff line number Diff line
@@ -567,6 +567,17 @@ r_args:
     rt_show_add_table($$, c->in_table);
     $$->tables_defined_by = RSD_TDB_DIRECT;
   }
 | r_args EXPORT TABLE CF_SYM_KNOWN '.' r_args_channel {
     cf_assert_symbol($4, SYM_PROTO);
     $$ = $1;
     struct proto_config *cf = $4->proto;
     if (!cf->proto) cf_error("%s is not a protocol", $4->name);
     struct channel *c = proto_find_channel_by_name(cf->proto, $6);
     if (!c) cf_error("Channel %s.%s not found", $4->name, $6);
     if (!c->out_table) cf_error("No export table in channel %s.%s", $4->name, $6);
     rt_show_add_table($$, c->out_table);
     $$->tables_defined_by = RSD_TDB_DIRECT;
   }
 | r_args FILTER filter {
     $$ = $1;
     if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice");
+26 −0
Original line number Diff line number Diff line
@@ -317,6 +317,13 @@ channel_reset_import(struct channel *c)
  rt_prune_sync(c->in_table, 1);
}

static void
channel_reset_export(struct channel *c)
{
  /* Just free the routes */
  rt_prune_sync(c->out_table, 1);
}

/* Called by protocol to activate in_table */
void
channel_setup_in_table(struct channel *c)
@@ -331,6 +338,18 @@ channel_setup_in_table(struct channel *c)
  c->reload_event = ev_new_init(c->proto->pool, channel_reload_loop, c);
}

/* Called by protocol to activate out_table */
void
channel_setup_out_table(struct channel *c)
{
  struct rtable_config *cf = mb_allocz(c->proto->pool, sizeof(struct rtable_config));
  cf->name = "export";
  cf->addr_type = c->net_type;

  c->out_table = mb_allocz(c->proto->pool, sizeof(struct rtable));
  rt_setup(c->proto->pool, c->out_table, cf);
}


static void
channel_do_start(struct channel *c)
@@ -376,6 +395,7 @@ channel_do_down(struct channel *c)

  c->in_table = NULL;
  c->reload_event = NULL;
  c->out_table = NULL;

  CALL(c->channel->cleanup, c);

@@ -411,6 +431,9 @@ channel_set_state(struct channel *c, uint state)
    if (c->in_table && (cs == CS_UP))
      channel_reset_import(c);

    if (c->out_table && (cs == CS_UP))
      channel_reset_export(c);

    break;

  case CS_UP:
@@ -433,6 +456,9 @@ channel_set_state(struct channel *c, uint state)
    if (c->in_table && (cs == CS_UP))
      channel_reset_import(c);

    if (c->out_table && (cs == CS_UP))
      channel_reset_export(c);

    channel_do_flush(c);
    break;

+3 −0
Original line number Diff line number Diff line
@@ -539,6 +539,8 @@ struct channel {
  struct event *reload_event;		/* Event responsible for reloading from in_table */
  struct fib_iterator reload_fit;	/* Iterator in in_table used during reloading */
  u8 reload_active;			/* Iterator reload_fit is linked */

  struct rtable *out_table;		/* Internal table for exported routes */
};


@@ -607,6 +609,7 @@ int proto_configure_channel(struct proto *p, struct channel **c, struct channel_

void channel_set_state(struct channel *c, uint state);
void channel_setup_in_table(struct channel *c);
void channel_setup_out_table(struct channel *c);
void channel_schedule_reload(struct channel *c);

static inline void channel_init(struct channel *c) { channel_set_state(c, CS_START); }
+1 −0
Original line number Diff line number Diff line
@@ -320,6 +320,7 @@ int rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src
int rt_reload_channel(struct channel *c);
void rt_reload_channel_abort(struct channel *c);
void rt_prune_sync(rtable *t, int all);
int rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, int refeed);
struct rtable_config *rt_new_table(struct symbol *s, uint addr_type);


Loading