Commit 9fdf9d29 authored by Ondrej Zajicek's avatar Ondrej Zajicek
Browse files

KRT: Add support for plenty of kernel route metrics

Linux kernel route metrics (RTA_METRICS netlink route attribute) are
represented and accessible as new route attributes:

krt_mtu, krt_window, krt_rtt, krt_rttvar, krt_sstresh, krt_cwnd, krt_advmss,
krt_reordering, krt_hoplimit, krt_initcwnd, krt_rto_min, krt_initrwnd,
krt_quickack, krt_lock_mtu, krt_lock_window, krt_lock_rtt, krt_lock_rttvar,
krt_lock_sstresh, krt_lock_cwnd, krt_lock_advmss, krt_lock_reordering,
krt_lock_hoplimit, krt_lock_rto_min, krt_feature_ecn, krt_feature_allfrag
parent 315f23a0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2248,7 +2248,7 @@ these attributes:

	<tag>ip <cf/krt_prefsrc/</tag> (Linux)
	The preferred source address. Used in source address selection for
 	outgoing packets. Have to be one of IP addresses of the router.
 	outgoing packets. Has to be one of the IP addresses of the router.

	<tag>int <cf/krt_realm/</tag> (Linux)
	The realm of the route. Can be used for traffic classification.
+6 −0
Original line number Diff line number Diff line
@@ -461,8 +461,14 @@ static inline void rt_lock_source(struct rte_src *src) { src->uc++; }
static inline void rt_unlock_source(struct rte_src *src) { src->uc--; }
void rt_prune_sources(void);

struct ea_walk_state {
  ea_list *eattrs;			/* Ccurrent ea_list, initially set by caller */
  eattr *ea;				/* Current eattr, initially NULL */
  u32 visited[4];			/* Bitfield, limiting max to 128 */
};

eattr *ea_find(ea_list *, unsigned ea);
eattr *ea_walk(struct ea_walk_state *s, uint id, uint max);
int ea_get_int(ea_list *, unsigned ea, int def);
void ea_dump(ea_list *);
void ea_sort(ea_list *);		/* Sort entries in all sub-lists */
+76 −0
Original line number Diff line number Diff line
@@ -307,6 +307,82 @@ ea_find(ea_list *e, unsigned id)
  return a;
}

/**
 * ea_walk - walk through extended attributes
 * @s: walk state structure
 * @id: start of attribute ID interval
 * @max: length of attribute ID interval
 *
 * Given an extended attribute list, ea_walk() walks through the list looking
 * for first occurrences of attributes with ID in specified interval from @id to
 * (@id + @max - 1), returning pointers to found &eattr structures, storing its
 * walk state in @s for subsequent calls.

 * The function ea_walk() is supposed to be called in a loop, with initially
 * zeroed walk state structure @s with filled the initial extended attribute
 * list, returning one found attribute in each call or %NULL when no other
 * attribute exists. The extended attribute list or the arguments should not be
 * modified between calls. The maximum value of @max is 128.
 */
eattr *
ea_walk(struct ea_walk_state *s, uint id, uint max)
{
  ea_list *e = s->eattrs;
  eattr *a = s->ea;
  eattr *a_max;

  max = id + max;

  if (a)
    goto step;

  for (; e; e = e->next)
  {
    if (e->flags & EALF_BISECT)
    {
      int l, r, m;

      l = 0;
      r = e->count - 1;
      while (l < r)
      {
	m = (l+r) / 2;
	if (e->attrs[m].id < id)
	  l = m + 1;
	else
	  r = m;
      }
      a = e->attrs + l;
    }
    else
      a = e->attrs;

  step:
    a_max = e->attrs + e->count;
    for (; a < a_max; a++)
      if ((a->id >= id) && (a->id < max))
      {
	int n = a->id - id;

	if (BIT32_TEST(s->visited, n))
	  continue;

	BIT32_SET(s->visited, n);

	if ((a->type & EAF_TYPE_MASK) == EAF_TYPE_UNDEF)
	  continue;

	s->eattrs = e;
	s->ea = a;
	return a;
      }
      else if (e->flags & EALF_BISECT)
	break;
  }

  return NULL;
}

/**
 * ea_get_int - fetch an integer attribute
 * @e: attribute list
+2 −0
Original line number Diff line number Diff line
@@ -44,5 +44,7 @@ struct krt_state {

static inline void krt_sys_init(struct krt_proto *p UNUSED) { }

static inline int krt_sys_get_attr(eattr *a UNUSED, byte *buf UNUSED, int buflen UNUSED) { }


#endif
+53 −0
Original line number Diff line number Diff line
@@ -32,6 +32,59 @@ static inline struct ifa * kif_get_primary_ip(struct iface *i) { return NULL; }

/* Kernel routes */

#define EA_KRT_PREFSRC		EA_CODE(EAP_KRT, 0x10)
#define EA_KRT_REALM		EA_CODE(EAP_KRT, 0x11)


#define KRT_METRICS_MAX		0x10	/* RTAX_QUICKACK+1 */
#define KRT_METRICS_OFFSET	0x20	/* Offset of EA_KRT_* vs RTAX_* */

#define KRT_FEATURES_MAX	4

/*
 * Following attributes are parts of RTA_METRICS kernel route attribute, their
 * ids must be consistent with their RTAX_* constants (+ KRT_METRICS_OFFSET)
 */
#define EA_KRT_METRICS		EA_CODE(EAP_KRT, 0x20)	/* Dummy one */
#define EA_KRT_LOCK		EA_CODE(EAP_KRT, 0x21)
#define EA_KRT_MTU		EA_CODE(EAP_KRT, 0x22)
#define EA_KRT_WINDOW		EA_CODE(EAP_KRT, 0x23)
#define EA_KRT_RTT		EA_CODE(EAP_KRT, 0x24)
#define EA_KRT_RTTVAR		EA_CODE(EAP_KRT, 0x25)
#define EA_KRT_SSTRESH		EA_CODE(EAP_KRT, 0x26)
#define EA_KRT_CWND		EA_CODE(EAP_KRT, 0x27)
#define EA_KRT_ADVMSS		EA_CODE(EAP_KRT, 0x28)
#define EA_KRT_REORDERING 	EA_CODE(EAP_KRT, 0x29)
#define EA_KRT_HOPLIMIT		EA_CODE(EAP_KRT, 0x2a)
#define EA_KRT_INITCWND		EA_CODE(EAP_KRT, 0x2b)
#define EA_KRT_FEATURES		EA_CODE(EAP_KRT, 0x2c)
#define EA_KRT_RTO_MIN		EA_CODE(EAP_KRT, 0x2d)
#define EA_KRT_INITRWND		EA_CODE(EAP_KRT, 0x2e)
#define EA_KRT_QUICKACK		EA_CODE(EAP_KRT, 0x2f)

/* Bits of EA_KRT_LOCK, also based on RTAX_* constants */
#define EA_KRT_LOCK_MTU		EA_KRT_LOCK | EA_BIT(0x2)
#define EA_KRT_LOCK_WINDOW	EA_KRT_LOCK | EA_BIT(0x3)
#define EA_KRT_LOCK_RTT		EA_KRT_LOCK | EA_BIT(0x4)
#define EA_KRT_LOCK_RTTVAR	EA_KRT_LOCK | EA_BIT(0x5)
#define EA_KRT_LOCK_SSTHRESH	EA_KRT_LOCK | EA_BIT(0x6)
#define EA_KRT_LOCK_CWND	EA_KRT_LOCK | EA_BIT(0x7)
#define EA_KRT_LOCK_ADVMSS	EA_KRT_LOCK | EA_BIT(0x8)
#define EA_KRT_LOCK_REORDERING 	EA_KRT_LOCK | EA_BIT(0x9)
#define EA_KRT_LOCK_HOPLIMIT	EA_KRT_LOCK | EA_BIT(0xa)
// define EA_KRT_LOCK_INITCWND	EA_KRT_LOCK | EA_BIT(0xb)
// define EA_KRT_LOCK_FEATURES	EA_KRT_LOCK | EA_BIT(0xc)
#define EA_KRT_LOCK_RTO_MIN	EA_KRT_LOCK | EA_BIT(0xd)
// define EA_KRT_LOCK_INITRWND	EA_KRT_LOCK | EA_BIT(0xe)

/* Bits of EA_KRT_FEATURES, based on RTAX_FEATURE_* constants */
#define EA_KRT_FEATURE_ECN	EA_KRT_FEATURES | EA_BIT(0x0)
// define EA_KRT_FEATURE_SACK	EA_KRT_FEATURES | EA_BIT(0x1)
// define EA_KRT_FEATURE_TSTAMP	EA_KRT_FEATURES | EA_BIT(0x2)
#define EA_KRT_FEATURE_ALLFRAG	EA_KRT_FEATURES | EA_BIT(0x3)



#define NL_NUM_TABLES 256

struct krt_params {
Loading