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

BGP: Handle export table internally

Handle export table internally in BGP protocol instead of in
channel and put there exported route after full BGP processing.
parent ee13f35d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -521,6 +521,7 @@ struct channel {
  struct fib_iterator reload_fit;	/* Iterator in in_table used during reloading */
  u8 reload_active;			/* Iterator reload_fit is linked */

  u8 out_table_int;			/* Update of out_table is handled internally by protocol */
  struct rtable *out_table;		/* Internal table for exported routes */
};

+2 −1
Original line number Diff line number Diff line
@@ -612,7 +612,8 @@ do_rt_notify(struct channel *c, net *net, rte *new, rte *old, ea_list *tmpa, int
	}
    }

  if (c->out_table && !rte_update_out(c, net->n.addr, new, old, &old_free, refeed))
  if (c->out_table && !c->out_table_int &&
      !rte_update_out(c, net->n.addr, new, old, &old_free, refeed))
    return;

  /* Use route from export_table as old */
+38 −0
Original line number Diff line number Diff line
@@ -1553,6 +1553,33 @@ bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old, ea
  {
    attrs = bgp_update_attrs(p, c, new, attrs, bgp_linpool2);

    if (c->c.out_table && c->c.out_table_int)
    {
      rte *old_free = NULL;
      rte *new1 = NULL;

      /* Prepare new1 as final route after bgp_update_attrs() attribute changes */
      if (attrs)
      {
	new1 = rte_cow_rta(new, bgp_linpool2);
	new1->attrs->eattrs = attrs;
      }

      /* Update out_table, we use 'new' as 'old' to ensure it is non-NULL */
      int drop = !rte_update_out(C, n->n.addr, new1, new, &old_free, new == old);

      if (new1 != new)
	rte_free(new1);
      if (old_free)
	rte_free(old_free);

      if (drop)
      {
	lp_flush(bgp_linpool2);
	return;
      }
    }

    /* If attributes are invalid, we fail back to withdraw */
    buck = attrs ? bgp_get_bucket(c, attrs) : bgp_get_withdraw_bucket(c);
    path = new->attrs->src->global_id;
@@ -1561,6 +1588,17 @@ bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old, ea
  }
  else
  {
    if (c->c.out_table && c->c.out_table_int)
    {
      rte *old_free = NULL;

      if (!rte_update_out(C, n->n.addr, new, old, &old_free, 0))
	return;

      if (old_free)
	rte_free(old_free);
    }

    buck = bgp_get_withdraw_bucket(c);
    path = old->attrs->src->global_id;
  }
+3 −0
Original line number Diff line number Diff line
@@ -1543,7 +1543,10 @@ bgp_channel_start(struct channel *C)
   channel_setup_in_table(C);

  if (c->cf->export_table)
  {
    channel_setup_out_table(C);
    C->out_table_int = 1;
  }

  c->next_hop_addr = c->cf->next_hop_addr;
  c->link_addr = IPA_NONE;