CF_DECLS
-CF_KEYWORDS(KERNEL, TABLE)
+CF_KEYWORDS(KERNEL, TABLE, METRIC)
CF_GRAMMAR
THIS_KRT->sys.table_id = $3;
}
+ | METRIC expr {
+ if ($2 && !krt_max_metric)
+ cf_error("Kernel route metric not supported");
+ if ($2 > krt_max_metric)
+ cf_error("Kernel table id must be in range 0-%u", krt_max_metric);
+
+ THIS_KRT->sys.metric = $2;
+ }
;
CF_CODE
* table_id is specified explicitly as sysctl scan argument, while in FreeBSD it
* is handled implicitly by changing default table using setfib() syscall.
*
+ * OpenBSD allows to use route metric. The behavior is controlled by these macro
+ * KRT_USE_METRIC, which enables use of rtm_priority in route send/recevive.
+ * There is also KRT_DEFAULT_METRIC and KRT_MAX_METRIC for default and maximum
+ * metric values.
+ *
* KRT_SHARED_SOCKET - use shared kernel socked instead of one for each krt_proto
* KRT_USE_SETFIB_SCAN - use setfib() for sysctl() route scan
* KRT_USE_SETFIB_SOCK - use SO_SETFIB socket option for kernel sockets
#ifdef __OpenBSD__
#define KRT_MAX_TABLES (RT_TABLEID_MAX+1)
+#define KRT_USE_METRIC
+#define KRT_MAX_METRIC 255
+#define KRT_DEFAULT_METRIC 56
#define KRT_SHARED_SOCKET
#define KRT_USE_SYSCTL_7
#endif
#define KRT_MAX_TABLES 1
#endif
+#ifndef KRT_MAX_METRIC
+#define KRT_MAX_METRIC 0
+#endif
+
+#ifndef KRT_DEFAULT_METRIC
+#define KRT_DEFAULT_METRIC 0
+#endif
+
/* Dynamic max number of tables */
#endif
+/* Make it available to parser code */
+const uint krt_max_metric = KRT_MAX_METRIC;
+
+
/* Route socket message processing */
int
msg.rtm.rtm_tableid = KRT_CF->sys.table_id;
#endif
+#ifdef KRT_USE_METRIC
+ msg.rtm.rtm_priority = KRT_CF->sys.metric;
+#endif
+
#ifdef RTF_REJECT
if(a->dest == RTD_UNREACHABLE)
msg.rtm.rtm_flags |= RTF_REJECT;
e = rte_get_temp(&a, p->p.main_source);
e->net = net;
- ea_list *ea = alloca(sizeof(ea_list) + 1 * sizeof(eattr));
+ ea_list *ea = alloca(sizeof(ea_list) + 2 * sizeof(eattr));
*ea = (ea_list) { .count = 1, .next = e->attrs->eattrs };
e->attrs->eattrs = ea;
.u.data = src2,
};
+#ifdef KRT_USE_METRIC
+ ea->count++;
+ ea->attrs[1] = (eattr) {
+ .id = EA_KRT_METRIC,
+ .type = EAF_TYPE_INT,
+ .u.data = msg->rtm.rtm_priority,
+ };
+#endif
+
if (scan)
krt_got_route(p, e, src);
else
int
krt_sys_reconfigure(struct krt_proto *p UNUSED, struct krt_config *n, struct krt_config *o)
{
- return n->sys.table_id == o->sys.table_id;
+ return (n->sys.table_id == o->sys.table_id) && (n->sys.metric == o->sys.metric);
}
void
void krt_sys_init_config(struct krt_config *c)
{
c->sys.table_id = 0; /* Default table */
+ c->sys.metric = KRT_DEFAULT_METRIC;
}
void krt_sys_copy_config(struct krt_config *d, struct krt_config *s)
{
d->sys.table_id = s->sys.table_id;
+ d->sys.metric = s->sys.metric;
}