diff options
Diffstat (limited to 'sysdep/unix')
-rw-r--r-- | sysdep/unix/krt.Y | 4 | ||||
-rw-r--r-- | sysdep/unix/krt.c | 17 | ||||
-rw-r--r-- | sysdep/unix/krt.h | 3 |
3 files changed, 18 insertions, 6 deletions
diff --git a/sysdep/unix/krt.Y b/sysdep/unix/krt.Y index 630cda38..e036081d 100644 --- a/sysdep/unix/krt.Y +++ b/sysdep/unix/krt.Y @@ -17,7 +17,7 @@ CF_DEFINES CF_DECLS -CF_KEYWORDS(KERNEL, PERSIST, SCAN, TIME, LEARN, DEVICE, ROUTES, GRACEFUL, RESTART, KRT_SOURCE, KRT_METRIC) +CF_KEYWORDS(KERNEL, PERSIST, SCAN, TIME, LEARN, DEVICE, ROUTES, GRACEFUL, RESTART, KRT_SOURCE, KRT_METRIC, MERGE, PATHS) CF_GRAMMAR @@ -47,6 +47,8 @@ kern_item: } | DEVICE ROUTES bool { THIS_KRT->devroutes = $3; } | GRACEFUL RESTART bool { THIS_KRT->graceful_restart = $3; } + | MERGE PATHS bool { THIS_KRT->merge_paths = $3 ? KRT_DEFAULT_ECMP_LIMIT : 0; } + | MERGE PATHS bool LIMIT expr { THIS_KRT->merge_paths = $3 ? $5 : 0; if (($5 <= 0) || ($5 > 255)) cf_error("Merge paths limit must be in range 1-255"); } ; /* Kernel interface protocol */ diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index d8d28c7c..2eab5cb2 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -595,9 +595,13 @@ krt_flush_routes(struct krt_proto *p) static struct rte * krt_export_net(struct krt_proto *p, net *net, rte **rt_free, ea_list **tmpa) { - struct filter *filter = p->p.main_ahook->out_filter; + struct announce_hook *ah = p->p.main_ahook; + struct filter *filter = ah->out_filter; rte *rt; + if (p->p.accept_ra_types == RA_MERGED) + return rt_export_merged(ah, net, rt_free, tmpa, 1); + rt = net->routes; *rt_free = NULL; @@ -1091,11 +1095,13 @@ krt_rte_same(rte *a, rte *b) struct krt_config *krt_cf; static struct proto * -krt_init(struct proto_config *c) +krt_init(struct proto_config *C) { - struct krt_proto *p = proto_new(c, sizeof(struct krt_proto)); + struct krt_proto *p = proto_new(C, sizeof(struct krt_proto)); + struct krt_config *c = (struct krt_config *) C; - p->p.accept_ra_types = RA_OPTIMAL; + p->p.accept_ra_types = c->merge_paths ? RA_MERGED : RA_OPTIMAL; + p->p.merge_limit = c->merge_paths; p->p.import_control = krt_import_control; p->p.rt_notify = krt_rt_notify; p->p.if_notify = krt_if_notify; @@ -1161,7 +1167,8 @@ krt_reconfigure(struct proto *p, struct proto_config *new) return 0; /* persist, graceful restart need not be the same */ - return o->scan_time == n->scan_time && o->learn == n->learn && o->devroutes == n->devroutes; + return o->scan_time == n->scan_time && o->learn == n->learn && + o->devroutes == n->devroutes && o->merge_paths == n->merge_paths; } static void diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h index 1940cbcd..9d5d4e8c 100644 --- a/sysdep/unix/krt.h +++ b/sysdep/unix/krt.h @@ -26,6 +26,8 @@ struct kif_proto; #define KRF_DELETE 3 /* Should be deleted */ #define KRF_IGNORE 4 /* To be ignored */ +#define KRT_DEFAULT_ECMP_LIMIT 16 + #define EA_KRT_SOURCE EA_CODE(EAP_KRT, 0) #define EA_KRT_METRIC EA_CODE(EAP_KRT, 1) @@ -47,6 +49,7 @@ struct krt_config { int learn; /* Learn routes from other sources */ int devroutes; /* Allow export of device routes */ int graceful_restart; /* Regard graceful restart recovery */ + int merge_paths; /* Exported routes are merged for ECMP */ }; struct krt_proto { |