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

Nest: Use bitmaps to keep track of exported routes

Use a hierarchical bitmap in a routing table to assign ids to routes, and
then use bitmaps (indexed by route id) in channels to keep track whether
routes were exported. This avoids unreliable and inefficient re-evaluation
of filters for old routes in order to determine whether they were exported.
parent af02b83b
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -26,6 +26,13 @@ bmap_init(struct bmap *b, pool *p, uint size)
  b->data = mb_allocz(p, b->size);
}

void
bmap_reset(struct bmap *b, uint size)
{
  b->size = BIRD_ALIGN(size, 4);
  memset(b->data, 0, b->size);
}

void
bmap_grow(struct bmap *b, uint need)
{
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ struct bmap
};

void bmap_init(struct bmap *b, pool *p, uint size);
void bmap_reset(struct bmap *b, uint size);
void bmap_grow(struct bmap *b, uint need);
void bmap_free(struct bmap *b);

+2 −1
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS)
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
CF_KEYWORDS(ALGORITHM, KEYED, HMAC, MD5, SHA1, SHA256, SHA384, SHA512)
CF_KEYWORDS(PRIMARY, STATS, COUNT, BY, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENERATE)
CF_KEYWORDS(PRIMARY, STATS, COUNT, BY, FOR, COMMANDS, PREEXPORT, NOEXPORT, EXPORTED, GENERATE)
CF_KEYWORDS(BGP, PASSWORDS, DESCRIPTION, SORTED)
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP)
CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, ROUTE, PROTOCOL, BASE, LOG, S, MS, US)
@@ -685,6 +685,7 @@ export_mode:
   PREEXPORT	{ $$ = RSEM_PREEXPORT; }
 | EXPORT	{ $$ = RSEM_EXPORT; }
 | NOEXPORT	{ $$ = RSEM_NOEXPORT; }
 | EXPORTED	{ $$ = RSEM_EXPORTED; }
 ;

/* This is ugly hack */
+23 −4
Original line number Diff line number Diff line
@@ -255,6 +255,22 @@ channel_feed_loop(void *ptr)
    return;
  }

  /* Reset export limit if the feed ended with acceptable number of exported routes */
  struct channel_limit *l = &c->out_limit;
  if (c->refeeding &&
      (l->state == PLS_BLOCKED) &&
      (c->refeed_count <= l->limit) &&
      (c->stats.exp_routes <= l->limit))
  {
    log(L_INFO "Protocol %s resets route export limit (%u)", c->proto->name, l->limit);
    channel_reset_limit(&c->out_limit);

    /* Continue in feed - it will process routing table again from beginning */
    c->refeed_count = 0;
    ev_schedule(c->feed_event);
    return;
  }

  // DBG("Feeding protocol %s finished\n", p->name);
  c->export_state = ES_READY;
  // proto_log_state_change(p);
@@ -282,6 +298,7 @@ channel_stop_export(struct channel *c)

  c->export_state = ES_DOWN;
  c->stats.exp_routes = 0;
  bmap_reset(&c->export_map, 1024);
}


@@ -360,6 +377,9 @@ channel_do_start(struct channel *c)

  c->feed_event = ev_new_init(c->proto->pool, channel_feed_loop, c);

  bmap_init(&c->export_map, c->proto->pool, 1024);
  memset(&c->stats, 0, sizeof(struct proto_stats));

  channel_reset_limit(&c->rx_limit);
  channel_reset_limit(&c->in_limit);
  channel_reset_limit(&c->out_limit);
@@ -391,6 +411,7 @@ channel_do_down(struct channel *c)
  if ((c->stats.imp_routes + c->stats.filt_routes) != 0)
    log(L_ERR "%s: Channel %s is down but still has some routes", c->proto->name, c->name);

  bmap_free(&c->export_map);
  memset(&c->stats, 0, sizeof(struct proto_stats));

  c->in_table = NULL;
@@ -503,10 +524,8 @@ channel_request_feeding(struct channel *c)
    rt_feed_channel_abort(c);
  }

  channel_reset_limit(&c->out_limit);

  /* Hack: reset exp_routes during refeed, and do not decrease it later */
  c->stats.exp_routes = 0;
  /* Track number of exported routes during refeed */
  c->refeed_count = 0;

  channel_schedule_feed(c, 0);	/* Sets ES_FEEDING */
  // proto_log_state_change(c);
+2 −0
Original line number Diff line number Diff line
@@ -507,6 +507,7 @@ struct channel {
  struct rtable *table;
  const struct filter *in_filter;	/* Input filter */
  const struct filter *out_filter;	/* Output filter */
  struct bmap export_map;		/* Keeps track which routes passed export filter */
  struct channel_limit rx_limit;	/* Receive limit (for in_keep_filtered) */
  struct channel_limit in_limit;	/* Input limit */
  struct channel_limit out_limit;	/* Output limit */
@@ -514,6 +515,7 @@ struct channel {
  struct event *feed_event;		/* Event responsible for feeding */
  struct fib_iterator feed_fit;		/* Routing table iterator used during feeding */
  struct proto_stats stats;		/* Per-channel protocol statistics */
  u32 refeed_count;			/* Number of routes exported during refeed regardless of out_limit */

  u8 net_type;				/* Routing table network type (NET_*), 0 for undefined */
  u8 ra_mode;				/* Mode of received route advertisements (RA_*) */
Loading