Commit f2010f9c authored by Jan Moskyto Matejka's avatar Jan Moskyto Matejka
Browse files

Static: Protocol rework wrt. struct nexthop changes; MPLS label support

parent 33ad6e01
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ CF_DECLS
  struct proto_spec ps;
  struct channel_limit cl;
  struct timeformat *tf;
  u32 *lbl;
}

%token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT
@@ -82,6 +83,7 @@ CF_DECLS
%type <a> ipa
%type <net> net_ip4_ net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa
%type <net_ptr> net_ net_any net_roa4_ net_roa6_ net_roa_
%type <lbl> label_stack_start label_stack

%type <t> text opttext

@@ -266,6 +268,22 @@ net_or_ipa:
   }
 ;

label_stack_start: NUM
{
  $$ = cfg_allocz(sizeof(u32) * (NEXTHOP_MAX_LABEL_STACK+1));
  $$[0] = 1;
  $$[1] = $1;
};

label_stack:
    label_stack_start
  | label_stack '/' NUM {
    if ($1[0] >= NEXTHOP_MAX_LABEL_STACK)
      cf_error("Too many labels in stack.");
    $1[++$1[0]] = $3;
    $$ = $1;
  }
;

datetime:
   TEXT {
+7 −7
Original line number Diff line number Diff line
@@ -4141,8 +4141,8 @@ specific destination for them and you don't want to send them out through the
default route to prevent routing loops).

<p>There are five types of static routes: `classical' routes telling to forward
packets to a neighboring router, multipath routes specifying several (possibly
weighted) neighboring routers, device routes specifying forwarding to hosts on a
packets to a neighboring router (single path or multipath, possibly weighted),
device routes specifying forwarding to hosts on a
directly connected network, recursive routes computing their nexthops by doing
route table lookups for a given IP, and special routes (sink, blackhole etc.)
which specify a special action to be done instead of forwarding the packet.
@@ -4174,14 +4174,14 @@ definition of the protocol contains mainly a list of static routes.
<p>Route definitions (each may also contain a block of per-route options):

<descrip>
	<tag><label id="static-route-via-ip">route <m/prefix/ via <m/ip/</tag>
	Static route through a neighboring router. For link-local next hops,
	<tag><label id="static-route-via-ip">route <m/prefix/ via <m/ip/ [mpls <m/num/[/<m/num/[/<m/num/[...]]]]</tag>
	Static single path route through a neighboring router. For link-local next hops,
	interface can be specified as a part of the address (e.g.,
	<cf/via fe80::1234%eth0/).
	<cf/via fe80::1234%eth0/). MPLS labels should be specified in outer-first order.

	<tag><label id="static-route-via-mpath">route <m/prefix/ multipath via <m/ip/ [weight <m/num/] [bfd <m/switch/] [via <m/.../]</tag>
	<tag><label id="static-route-via-mpath">route <m/prefix/ via <m/ip/ [mpls <m/num/[/<m/num/[/<m/num/[...]]]] [weight <m/num/] [bfd <m/switch/] [via ...]</tag>
	Static multipath route. Contains several nexthops (gateways), possibly
	with their weights.
	with their weights and MPLS labels.

	<tag><label id="static-route-via-iface">route <m/prefix/ via <m/"interface"/</tag>
	Static device route through an interface to hosts on a directly
+2 −0
Original line number Diff line number Diff line
@@ -513,6 +513,7 @@ ea_list *ea_append(ea_list *to, ea_list *what);
void ea_format_bitfield(struct eattr *a, byte *buf, int bufsize, const char **names, int min, int max);

#define NEXTHOP_MAX_LABEL_STACK 8
#define NEXTHOP_MAX_SIZE (sizeof(struct nexthop) + sizeof(u32)*NEXTHOP_MAX_LABEL_STACK)

static inline size_t nexthop_size(const struct nexthop *nh)
{ return sizeof(struct nexthop) + sizeof(u32)*nh->labels; }
@@ -527,6 +528,7 @@ int nexthop_is_sorted(struct nexthop *x);

void rta_init(void);
static inline size_t rta_size(const rta *a) { return sizeof(rta) + sizeof(u32)*a->nh.labels; }
#define RTA_MAX_SIZE (sizeof(rta) + sizeof(u32)*NEXTHOP_MAX_LABEL_STACK)
rta *rta_lookup(rta *);			/* Get rta equivalent to this one, uc++ */
static inline int rta_is_cached(rta *r) { return r->aflags & RTAF_CACHED; }
static inline rta *rta_clone(rta *r) { r->uc++; return r; }
+9 −0
Original line number Diff line number Diff line
@@ -330,6 +330,9 @@ nexthop_copy(struct nexthop *o)
      n->iface = o->iface;
      n->next = NULL;
      n->weight = o->weight;
      n->labels = o->labels;
      for (int i=0; i<o->labels; i++)
	n->label[i] = o->label[i];

      *last = n;
      last = &(n->next);
@@ -1176,6 +1179,12 @@ rta_do_cow(rta *o, linpool *lp)
{
  rta *r = lp_alloc(lp, rta_size(o));
  memcpy(r, o, rta_size(o));
  for (struct nexthop **nhn = &(r->nh.next), *nho = o->nh.next; nho; nho = nho->next)
    {
      *nhn = lp_alloc(lp, nexthop_size(nho));
      memcpy(*nhn, nho, nexthop_size(nho));
      nhn = &((*nhn)->next);
    }
  r->aflags = 0;
  r->uc = 0;
  return r;
+17 −11
Original line number Diff line number Diff line
@@ -2443,14 +2443,7 @@ rt_format_via(rte *e)

  switch (a->dest)
    {
    case RTD_UNICAST:	if (a->nh.next)
			  bsprintf(via, "multipath");
			else
			  {
			    if (ipa_nonzero(a->nh.gw)) bsprintf(via, "via %I ", a->nh.gw);
			    bsprintf(via, "dev %s", a->nh.iface->name);
			  }
			break;
    case RTD_UNICAST:	bsprintf(via, "unicast"); break;
    case RTD_BLACKHOLE:	bsprintf(via, "blackhole"); break;
    case RTD_UNREACHABLE:	bsprintf(via, "unreachable"); break;
    case RTD_PROHIBIT:	bsprintf(via, "prohibited"); break;
@@ -2492,11 +2485,24 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm
    bsprintf(info, " (%d)", e->pref);
  cli_printf(c, -1007, "%-18s %s [%s %s%s]%s%s", ia, rt_format_via(e), a->src->proto->name,
	     tm, from, primary ? (sync_error ? " !" : " *") : "", info);
  if (a->nh.next)
  for (nh = &(a->nh); nh; nh = nh->next)
      cli_printf(c, -1007, "\tvia %I on %s weight %d", nh->gw, nh->iface->name, nh->weight + 1);
    {
      char ls[NEXTHOP_MAX_LABEL_STACK*8 + 5]; char *lsp = ls;
      if (nh->labels)
	{
	  lsp += bsprintf(lsp, " mpls %d", nh->label[0]);
	  for (int i=1;i<nh->labels; i++)
	    lsp += bsprintf(lsp, "/%d", nh->label[i]);
	  *lsp++ = '\0';
	}
      if (a->nh.next)
	cli_printf(c, -1007, "\tvia %I%s on %s weight %d", nh->gw, (nh->labels ? ls : ""), nh->iface->name, nh->weight + 1);
      else
	cli_printf(c, -1007, "\tvia %I%s on %s", nh->gw, (nh->labels ? ls : ""), nh->iface->name);
    }
  if (d->verbose)
    rta_show(c, a, tmpa);

}

static void
Loading