Commit adebcd5e authored by Maria Matejka's avatar Maria Matejka
Browse files

Babel: Convert the rte-local attributes to extended attributes

parent 083e0dbb
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -222,13 +222,6 @@ typedef struct rte {
  byte pflags;				/* Protocol-specific flags */
  btime lastmod;			/* Last modified */
  union {				/* Protocol-dependent data (metrics etc.) */
#ifdef CONFIG_BABEL
    struct {
      u16 seqno;			/* Babel seqno */
      u16 metric;			/* Babel metric */
      u64 router_id;			/* Babel router id */
    } babel;
#endif
    struct {				/* Routes generated by krt sync (both temporary and inherited ones) */
      s8 src;				/* Alleged route source (see krt.h) */
      u8 proto;				/* Kernel source protocol ID */
+47 −43
Original line number Diff line number Diff line
@@ -639,16 +639,33 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
      .from = r->neigh->addr,
      .nh.gw = r->next_hop,
      .nh.iface = r->neigh->ifa->iface,
      .eattrs = alloca(sizeof(ea_list) + 3*sizeof(eattr)),
    };

    *a0.eattrs = (ea_list) { .count = 3 };
    a0.eattrs->attrs[0] = (eattr) {
      .id = EA_BABEL_METRIC,
      .type = EAF_TYPE_INT,
      .u.data = r->metric,
    };

    struct adata *ad = alloca(sizeof(struct adata) + sizeof(u64));
    ad->length = sizeof(u64);
    memcpy(ad->data, &(r->router_id), sizeof(u64));
    a0.eattrs->attrs[1] = (eattr) {
      .id = EA_BABEL_ROUTER_ID,
      .type = EAF_TYPE_OPAQUE,
      .u.ptr = ad,
    };

    a0.eattrs->attrs[2] = (eattr) {
      .id = EA_BABEL_SEQNO,
      .type = EAF_TYPE_INT,
      .u.data = r->seqno,
    };

    rte e0 = {
      .attrs = &a0,
      .u.babel = {
	.seqno = r->seqno,
	.metric = r->metric,
	.router_id = r->router_id,
      },
      .pflags = EA_ID_FLAG(EA_BABEL_METRIC) | EA_ID_FLAG(EA_BABEL_ROUTER_ID),
    };

    e->unreachable = 0;
@@ -1851,7 +1868,10 @@ babel_dump(struct proto *P)
static void
babel_get_route_info(rte *rte, byte *buf)
{
  buf += bsprintf(buf, " (%d/%d) [%lR]", rte->attrs->pref, rte->u.babel.metric, rte->u.babel.router_id);
  u64 rid;
  memcpy(&rid, ea_find(rte->attrs->eattrs, EA_BABEL_ROUTER_ID)->u.ptr->data, sizeof(u64));
  buf += bsprintf(buf, " (%d/%d) [%lR]", rte->attrs->pref,
      ea_find(rte->attrs->eattrs, EA_BABEL_METRIC)->u.data, rid);
}

static int
@@ -1859,6 +1879,10 @@ babel_get_attr(const eattr *a, byte *buf, int buflen UNUSED)
{
  switch (a->id)
  {
  case EA_BABEL_SEQNO:
    bsprintf(buf, "seqno: %d", a->u.data);
    return GA_FULL;

  case EA_BABEL_METRIC:
    bsprintf(buf, "metric: %d", a->u.data);
    return GA_FULL;
@@ -2092,27 +2116,6 @@ babel_preexport(struct proto *P, struct rte **new, struct linpool *pool UNUSED)
  return 0;
}

static void
babel_make_tmp_attrs(struct rte *rt, struct linpool *pool)
{
  struct adata *id = lp_alloc_adata(pool, sizeof(u64));
  memcpy(id->data, &rt->u.babel.router_id, sizeof(u64));

  rte_init_tmp_attrs(rt, pool, 2);
  rte_make_tmp_attr(rt, EA_BABEL_METRIC, EAF_TYPE_INT, rt->u.babel.metric);
  rte_make_tmp_attr(rt, EA_BABEL_ROUTER_ID, EAF_TYPE_OPAQUE, (uintptr_t) id);
}

static void
babel_store_tmp_attrs(struct rte *rt, struct linpool *pool)
{
  rte_init_tmp_attrs(rt, pool, 2);
  rt->u.babel.metric = rte_store_tmp_attr(rt, EA_BABEL_METRIC);

  /* EA_BABEL_ROUTER_ID is read-only, we do not really save the value */
  rte_store_tmp_attr(rt, EA_BABEL_ROUTER_ID);
}

/*
 * babel_rt_notify - core tells us about new route (possibly our own),
 * so store it into our data structures.
@@ -2127,10 +2130,20 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net,
  if (new)
  {
    /* Update */
    uint internal = (new->attrs->src->proto == P);
    uint rt_seqno = internal ? new->u.babel.seqno : p->update_seqno;
    uint rt_seqno;
    uint rt_metric = ea_get_int(new->attrs->eattrs, EA_BABEL_METRIC, 0);
    u64 rt_router_id = internal ? new->u.babel.router_id : p->router_id;
    u64 rt_router_id;

    if (new->attrs->src->proto == P)
    {
      rt_seqno = ea_find(new->attrs->eattrs, EA_BABEL_SEQNO)->u.data;
      memcpy(&rt_router_id, ea_find(new->attrs->eattrs, EA_BABEL_ROUTER_ID)->u.ptr->data, sizeof(u64));
    }
    else
    {
      rt_seqno = p->router_id;
      rt_router_id = p->router_id;
    }

    if (rt_metric > BABEL_INFINITY)
    {
@@ -2173,18 +2186,12 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net,
static int
babel_rte_better(struct rte *new, struct rte *old)
{
  return new->u.babel.metric < old->u.babel.metric;
}
  uint new_metric = ea_find(new->attrs->eattrs, EA_BABEL_SEQNO)->u.data;
  uint old_metric = ea_find(old->attrs->eattrs, EA_BABEL_SEQNO)->u.data;

static int
babel_rte_same(struct rte *new, struct rte *old)
{
  return ((new->u.babel.seqno == old->u.babel.seqno) &&
	  (new->u.babel.metric == old->u.babel.metric) &&
	  (new->u.babel.router_id == old->u.babel.router_id));
  return new_metric < old_metric;
}


static void
babel_postconfig(struct proto_config *CF)
{
@@ -2215,10 +2222,7 @@ babel_init(struct proto_config *CF)
  P->if_notify = babel_if_notify;
  P->rt_notify = babel_rt_notify;
  P->preexport = babel_preexport;
  P->make_tmp_attrs = babel_make_tmp_attrs;
  P->store_tmp_attrs = babel_store_tmp_attrs;
  P->rte_better = babel_rte_better;
  P->rte_same = babel_rte_same;

  return P;
}
+1 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

#define EA_BABEL_METRIC		EA_CODE(PROTOCOL_BABEL, 0)
#define EA_BABEL_ROUTER_ID	EA_CODE(PROTOCOL_BABEL, 1)
#define EA_BABEL_SEQNO		EA_CODE(PROTOCOL_BABEL, 2)

#define BABEL_MAGIC		42
#define BABEL_VERSION		2