Commit 5f0cb61d authored by Maria Matejka's avatar Maria Matejka Committed by Maria Matejka
Browse files

OSPF: Convert the rte-local attributes to extended attributes

parent a0e4c664
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -244,13 +244,6 @@ typedef struct rte {
  byte pflags;				/* Protocol-specific flags */
  btime lastmod;			/* Last modified */
  union {				/* Protocol-dependent data (metrics etc.) */
#ifdef CONFIG_OSPF
    struct {
      u32 metric1, metric2;		/* OSPF Type 1 and Type 2 metrics */
      u32 tag;				/* External route tag */
      u32 router_id;			/* Router that originated this route */
    } ospf;
#endif
#ifdef CONFIG_BGP
    struct {
      u8 suppressed;			/* Used for deterministic MED comparison */
+23 −48
Original line number Diff line number Diff line
@@ -108,11 +108,8 @@
#include "ospf.h"

static int ospf_preexport(struct proto *P, rte *new);
static void ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool);
static void ospf_store_tmp_attrs(struct rte *rt, struct linpool *pool);
static void ospf_reload_routes(struct channel *C);
static int ospf_rte_better(struct rte *new, struct rte *old);
static int ospf_rte_same(struct rte *new, struct rte *old);
static u32 ospf_rte_igp_metric(struct rte *rt);
static void ospf_disp(timer *timer);

@@ -379,10 +376,7 @@ ospf_init(struct proto_config *CF)
  P->reload_routes = ospf_reload_routes;
  P->feed_begin = ospf_feed_begin;
  P->feed_end = ospf_feed_end;
  P->make_tmp_attrs = ospf_make_tmp_attrs;
  P->store_tmp_attrs = ospf_store_tmp_attrs;
  P->rte_better = ospf_rte_better;
  P->rte_same = ospf_rte_same;
  P->rte_igp_metric = ospf_rte_igp_metric;

  return P;
@@ -392,7 +386,9 @@ ospf_init(struct proto_config *CF)
static int
ospf_rte_better(struct rte *new, struct rte *old)
{
  if (new->u.ospf.metric1 == LSINFINITY)
  u32 new_metric1 = ea_get_int(new->attrs->eattrs, EA_OSPF_METRIC1, LSINFINITY);

  if (new_metric1 == LSINFINITY)
    return 0;

  if(new->attrs->source < old->attrs->source) return 1;
@@ -400,31 +396,26 @@ ospf_rte_better(struct rte *new, struct rte *old)

  if(new->attrs->source == RTS_OSPF_EXT2)
  {
    if(new->u.ospf.metric2 < old->u.ospf.metric2) return 1;
    if(new->u.ospf.metric2 > old->u.ospf.metric2) return 0;
    u32 old_metric2 = ea_get_int(old->attrs->eattrs, EA_OSPF_METRIC2, LSINFINITY);
    u32 new_metric2 = ea_get_int(new->attrs->eattrs, EA_OSPF_METRIC2, LSINFINITY);
    if(new_metric2 < old_metric2) return 1;
    if(new_metric2 > old_metric2) return 0;
  }

  if (new->u.ospf.metric1 < old->u.ospf.metric1)
  u32 old_metric1 = ea_get_int(old->attrs->eattrs, EA_OSPF_METRIC1, LSINFINITY);
  if (new_metric1 < old_metric1)
    return 1;

  return 0;			/* Old is shorter or same */
}

static int
ospf_rte_same(struct rte *new, struct rte *old)
{
  /* new->attrs == old->attrs always */
  return
    new->u.ospf.metric1 == old->u.ospf.metric1 &&
    new->u.ospf.metric2 == old->u.ospf.metric2 &&
    new->u.ospf.tag == old->u.ospf.tag &&
    new->u.ospf.router_id == old->u.ospf.router_id;
}

static u32
ospf_rte_igp_metric(struct rte *rt)
{
  return rt->u.ospf.metric1;
  if (rt->attrs->source == RTS_OSPF_EXT2)
    return IGP_METRIC_UNKNOWN;

  return ea_get_int(rt->attrs->eattrs, EA_OSPF_METRIC1, LSINFINITY);
}

void
@@ -507,26 +498,6 @@ ospf_preexport(struct proto *P, rte *e)
  return 0;
}

static void
ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool)
{
  rte_init_tmp_attrs(rt, pool, 4);
  rte_make_tmp_attr(rt, EA_OSPF_METRIC1, EAF_TYPE_INT, rt->u.ospf.metric1);
  rte_make_tmp_attr(rt, EA_OSPF_METRIC2, EAF_TYPE_INT, rt->u.ospf.metric2);
  rte_make_tmp_attr(rt, EA_OSPF_TAG, EAF_TYPE_INT, rt->u.ospf.tag);
  rte_make_tmp_attr(rt, EA_OSPF_ROUTER_ID, EAF_TYPE_ROUTER_ID, rt->u.ospf.router_id);
}

static void
ospf_store_tmp_attrs(struct rte *rt, struct linpool *pool)
{
  rte_init_tmp_attrs(rt, pool, 4);
  rt->u.ospf.metric1 = rte_store_tmp_attr(rt, EA_OSPF_METRIC1);
  rt->u.ospf.metric2 = rte_store_tmp_attr(rt, EA_OSPF_METRIC2);
  rt->u.ospf.tag = rte_store_tmp_attr(rt, EA_OSPF_TAG);
  rt->u.ospf.router_id = rte_store_tmp_attr(rt, EA_OSPF_ROUTER_ID);
}

/**
 * ospf_shutdown - Finish of OSPF instance
 * @P: OSPF protocol instance
@@ -616,16 +587,20 @@ ospf_get_route_info(rte * rte, byte * buf)
  }

  buf += bsprintf(buf, " %s", type);
  buf += bsprintf(buf, " (%d/%d", rte->attrs->pref, rte->u.ospf.metric1);
  buf += bsprintf(buf, " (%d/%d", rte->attrs->pref, ea_get_int(rte->attrs->eattrs, EA_OSPF_METRIC1, LSINFINITY));
  if (rte->attrs->source == RTS_OSPF_EXT2)
    buf += bsprintf(buf, "/%d", rte->u.ospf.metric2);
    buf += bsprintf(buf, "/%d", ea_get_int(rte->attrs->eattrs, EA_OSPF_METRIC2, LSINFINITY));
  buf += bsprintf(buf, ")");
  if ((rte->attrs->source == RTS_OSPF_EXT1 || rte->attrs->source == RTS_OSPF_EXT2) && rte->u.ospf.tag)
  if (rte->attrs->source == RTS_OSPF_EXT1 || rte->attrs->source == RTS_OSPF_EXT2)
  {
    buf += bsprintf(buf, " [%x]", rte->u.ospf.tag);
    eattr *ea = ea_find(rte->attrs->eattrs, EA_OSPF_TAG);
    if (ea && (ea->u.data > 0))
      buf += bsprintf(buf, " [%x]", ea->u.data);
  }
  if (rte->u.ospf.router_id)
    buf += bsprintf(buf, " [%R]", rte->u.ospf.router_id);
  
  eattr *ea = ea_find(rte->attrs->eattrs, EA_OSPF_ROUTER_ID);
  if (ea)
    buf += bsprintf(buf, " [%R]", ea->u.data);
}

static int
+34 −12
Original line number Diff line number Diff line
@@ -2062,23 +2062,45 @@ again1:

      if (reload || ort_changed(nf, &a0))
      {
	a0.eattrs = alloca(sizeof(ea_list) + 4 * sizeof(eattr));
	memset(a0.eattrs, 0, sizeof(ea_list));

	nf->old_metric1 = nf->n.metric1;
	nf->old_metric2 = nf->n.metric2;
	nf->old_tag = nf->n.tag;
	nf->old_rid = nf->n.rid;

	a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
	  .id = EA_OSPF_METRIC1,
	  .type = EAF_TYPE_INT,
	  .u.data = nf->n.metric1,
	};

	if (nf->n.type == RTS_OSPF_EXT2)
	  a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
	    .id = EA_OSPF_METRIC2,
	    .type = EAF_TYPE_INT,
	    .u.data = nf->n.metric2,
	  };

	if ((nf->n.type == RTS_OSPF_EXT1) || (nf->n.type == RTS_OSPF_EXT2))
	  a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
	    .id = EA_OSPF_TAG,
	    .type = EAF_TYPE_INT,
	    .u.data = nf->n.tag,
	  };

	a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
	  .id = EA_OSPF_ROUTER_ID,
	  .type = EAF_TYPE_ROUTER_ID,
	  .u.data = nf->n.rid,
	};

	rta *a = rta_lookup(&a0);
	rte *e = rte_get_temp(a, p->p.main_source);

	rta_free(nf->old_rta);
	nf->old_rta = rta_clone(a);
	e->u.ospf.metric1 = nf->old_metric1 = nf->n.metric1;
	e->u.ospf.metric2 = nf->old_metric2 = nf->n.metric2;
	e->u.ospf.tag = nf->old_tag = nf->n.tag;
	e->u.ospf.router_id = nf->old_rid = nf->n.rid;
	e->pflags = EA_ID_FLAG(EA_OSPF_METRIC1) | EA_ID_FLAG(EA_OSPF_ROUTER_ID);

	if (nf->n.type == RTS_OSPF_EXT2)
	  e->pflags |= EA_ID_FLAG(EA_OSPF_METRIC2);

	/* Perhaps onfly if tag is non-zero? */
	if ((nf->n.type == RTS_OSPF_EXT1) || (nf->n.type == RTS_OSPF_EXT2))
	  e->pflags |= EA_ID_FLAG(EA_OSPF_TAG);

	DBG("Mod rte type %d - %N via %I on iface %s, met %d\n",
	    a0.source, nf->fn.addr, a0.gw, a0.iface ? a0.iface->name : "(none)", nf->n.metric1);