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

Implement onlink flag for nexthops

Add proper support for per-nexthop onlink flag in routes to handle next
hop addresses that are not covered by interface IP ranges. Supported by
kernel and static protocols.

Thanks to Vincent Bernat for the idea.
parent 5220cb63
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -366,12 +366,16 @@ struct nexthop {
  ip_addr gw;				/* Next hop */
  struct iface *iface;			/* Outgoing interface */
  struct nexthop *next;
  byte flags;
  byte weight;
  byte labels_orig;			/* Number of labels before hostentry was applied */
  byte labels;				/* Number of all labels */
  u32 label[0];
};

#define RNF_ONLINK		0x1	/* Gateway is onlink regardless of IP ranges */


struct rte_src {
  struct rte_src *next;			/* Hash chain */
  struct proto *proto;			/* Protocol the source is based on */
+5 −1
Original line number Diff line number Diff line
@@ -171,7 +171,9 @@ nexthop__same(struct nexthop *x, struct nexthop *y)
{
  for (; x && y; x = x->next, y = y->next)
  {
    if (!ipa_equal(x->gw, y->gw) || (x->iface != y->iface) || (x->weight != y->weight) || (x->labels != y->labels))
    if (!ipa_equal(x->gw, y->gw) || (x->iface != y->iface) ||
	(x->flags != y->flags) || (x->weight != y->weight) ||
	(x->labels != y->labels))
      return 0;

    for (int i = 0; i < x->labels; i++)
@@ -193,6 +195,8 @@ nexthop_compare_node(struct nexthop *x, struct nexthop *y)
  if (!y)
    return -1;

  /* Should we also compare flags ? */

  r = ((int) y->weight) - ((int) x->weight);
  if (r)
    return r;
+5 −2
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm
    for (nh = &(a->nh); nh; nh = nh->next)
    {
      char mpls[MPLS_MAX_LABEL_STACK*12 + 5], *lsp = mpls;
      char *onlink = (nh->flags & RNF_ONLINK) ? " onlink" : "";

      if (nh->labels)
        {
@@ -80,9 +81,11 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm
      *lsp = '\0';

      if (a->nh.next)
	cli_printf(c, -1007, "\tvia %I%s on %s weight %d", nh->gw, mpls, nh->iface->name, nh->weight + 1);
	cli_printf(c, -1007, "\tvia %I%s on %s%s weight %d",
		   nh->gw, mpls, nh->iface->name, onlink, nh->weight + 1);
      else
	cli_printf(c, -1007, "\tvia %I%s on %s", nh->gw, mpls, nh->iface->name);
	cli_printf(c, -1007, "\tvia %I%s on %s%s",
		   nh->gw, mpls, nh->iface->name, onlink);
    }

  if (d->verbose)
+4 −1
Original line number Diff line number Diff line
@@ -1819,7 +1819,10 @@ no_nexthop:
      }
    }
    if (ipa_nonzero(nh->gw))
    {
      nhp->gw = nh->gw;			/* Router nexthop */
      nhp->flags |= (nh->flags & RNF_ONLINK);
    }
    else if (ipa_nonzero(he->link))
      nhp->gw = he->link;		/* Device nexthop with link-local address known */
    else
+4 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ static_route_finish(void)
CF_DECLS

CF_KEYWORDS(STATIC, ROUTE, VIA, DROP, REJECT, PROHIBIT, PREFERENCE, CHECK, LINK)
CF_KEYWORDS(WEIGHT, RECURSIVE, IGP, TABLE, BLACKHOLE, UNREACHABLE, BFD, MPLS)
CF_KEYWORDS(ONLINK, WEIGHT, RECURSIVE, IGP, TABLE, BLACKHOLE, UNREACHABLE, BFD, MPLS)


CF_GRAMMAR
@@ -87,6 +87,9 @@ stat_nexthop:
  | stat_nexthop MPLS label_stack {
    this_snh->mls = $3;
  }
  | stat_nexthop ONLINK bool {
    this_snh->onlink = $3;
  }
  | stat_nexthop WEIGHT expr {
    this_snh->weight = $3 - 1;
    if (($3<1) || ($3>256)) cf_error("Weight must be in range 1-256");
Loading