diff --git a/sysdep/bsd/krt-iface.h b/sysdep/bsd/krt-iface.h index 7f0d52bd..278c4be9 100644 --- a/sysdep/bsd/krt-iface.h +++ b/sysdep/bsd/krt-iface.h @@ -13,13 +13,21 @@ * We don't have split iface/scan/set parts. See krt-sock.h. */ -struct krt_if_params { +struct kif_params { }; -struct krt_if_status { +struct kif_status { }; -static inline int kif_params_same(struct krt_if_params *old UNUSED, struct krt_if_params *new UNUSED) { return 1; } -static inline void kif_copy_params(struct krt_if_params *dest UNUSED, struct krt_if_params *src UNUSED) { } + +static inline void kif_sys_init(struct kif_proto *p UNUSED) { } +static inline int kif_sys_reconfigure(struct kif_proto *p UNUSED, struct kif_config *n UNUSED, struct kif_config *o UNUSED) { return 1; } + +static inline void kif_sys_preconfig(struct config *c UNUSED) { } +static inline void kif_sys_postconfig(struct kif_config *c UNUSED) { } +static inline void kif_sys_init_config(struct kif_config *c UNUSED) { } +static inline void kif_sys_copy_config(struct kif_config *d UNUSED, struct kif_config *s UNUSED) { } + +static inline void kif_sys_io_init(void) { } #endif diff --git a/sysdep/bsd/krt-scan.h b/sysdep/bsd/krt-scan.h index 19cd930d..045b9e77 100644 --- a/sysdep/bsd/krt-scan.h +++ b/sysdep/bsd/krt-scan.h @@ -13,10 +13,18 @@ struct krt_scan_params { }; struct krt_scan_status { - list temp_ifs; /* Temporary interfaces */ }; -static inline int krt_scan_params_same(struct krt_scan_params *o UNUSED, struct krt_scan_params *n UNUSED) { return 1; } -static inline void krt_scan_copy_params(struct krt_scan_params *d UNUSED, struct krt_scan_params *s UNUSED) { } + +static inline void krt_sys_init(struct krt_proto *p UNUSED) { } +static inline int krt_sys_reconfigure(struct krt_proto *p UNUSED, struct krt_config *n UNUSED, struct krt_config *o UNUSED) { return 1; } + +static inline void krt_sys_preconfig(struct config *c UNUSED) { } +static inline void krt_sys_postconfig(struct krt_config *c UNUSED) { } +static inline void krt_sys_init_config(struct krt_config *c UNUSED) { } +static inline void krt_sys_copy_config(struct krt_config *d UNUSED, struct krt_config *s UNUSED) { } + + + #endif diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index 9ca36d83..5fb5f9f7 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -33,7 +33,19 @@ #include "lib/string.h" #include "lib/socket.h" -int rt_sock = 0; + +#ifndef RTAX_MAX +#define RTAX_MAX 8 +#endif + +struct ks_msg +{ + struct rt_msghdr rtm; + struct sockaddr_storage buf[RTAX_MAX]; +}; + + +static int rt_sock = 0; int krt_capable(rte *e) @@ -189,8 +201,8 @@ krt_sock_send(int cmd, rte *e) } void -krt_set_notify(struct krt_proto *p UNUSED, net *n, rte *new, rte *old, - struct ea_list *eattrs UNUSED) +krt_do_notify(struct krt_proto *p UNUSED, net *n, rte *new, rte *old, + struct ea_list *eattrs UNUSED) { int err = 0; @@ -206,45 +218,6 @@ krt_set_notify(struct krt_proto *p UNUSED, net *n, rte *new, rte *old, n->n.flags &= ~KRF_SYNC_ERROR; } -static int -krt_set_hook(sock *sk, int size UNUSED) -{ - struct ks_msg msg; - int l = read(sk->fd, (char *)&msg, sizeof(msg)); - - if(l <= 0) - log(L_ERR "krt-sock: read failed"); - else - krt_read_msg((struct proto *)sk->data, &msg, 0); - - return 0; -} - -void -krt_set_start(struct krt_proto *x, int first UNUSED) -{ - sock *sk_rt; - static int ks_open_tried = 0; - - if (ks_open_tried) - return; - - ks_open_tried = 1; - - DBG("KRT: Opening kernel socket\n"); - - if( (rt_sock = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC)) < 0) - die("Cannot open kernel socket for routes"); - - sk_rt = sk_new(krt_pool); - sk_rt->type = SK_MAGIC; - sk_rt->rx_hook = krt_set_hook; - sk_rt->fd = rt_sock; - sk_rt->data = x; - if (sk_open(sk_rt)) - bug("krt-sock: sk_open failed"); -} - #define SKIP(ARG...) do { DBG("KRT: Ignoring route - " ARG); return; } while(0) static void @@ -648,32 +621,6 @@ krt_read_msg(struct proto *p, struct ks_msg *msg, int scan) } } -void -krt_scan_construct(struct krt_config *c UNUSED) -{ -} - -void -krt_scan_preconfig(struct config *c UNUSED) -{ -} - -void -krt_scan_postconfig(struct krt_config *c UNUSED) -{ -} - -void -krt_scan_start(struct krt_proto *x, int first UNUSED) -{ - init_list(&x->scan.temp_ifs); -} - -void -krt_scan_shutdown(struct krt_proto *x UNUSED, int last UNUSED) -{ -} - static void krt_sysctl_scan(struct proto *p, pool *pool, byte **buf, size_t *bl, int cmd) { @@ -732,13 +679,13 @@ static size_t krt_buflen = 32768; static size_t kif_buflen = 4096; void -krt_scan_fire(struct krt_proto *p) +krt_do_scan(struct krt_proto *p) { krt_sysctl_scan((struct proto *)p, p->krt_pool, &krt_buffer, &krt_buflen, NET_RT_DUMP); } void -krt_if_scan(struct kif_proto *p) +kif_do_scan(struct kif_proto *p) { struct proto *P = (struct proto *)p; if_start_update(); @@ -746,14 +693,47 @@ krt_if_scan(struct kif_proto *p) if_end_update(); } - -void -krt_set_construct(struct krt_config *c UNUSED) +static int +krt_sock_hook(sock *sk, int size UNUSED) { + struct ks_msg msg; + int l = read(sk->fd, (char *)&msg, sizeof(msg)); + + if(l <= 0) + log(L_ERR "krt-sock: read failed"); + else + krt_read_msg((struct proto *)sk->data, &msg, 0); + + return 0; } void -krt_set_shutdown(struct krt_proto *x UNUSED, int last UNUSED) +krt_sys_start(struct krt_proto *x, int first UNUSED) +{ + sock *sk_rt; + static int ks_open_tried = 0; + + if (ks_open_tried) + return; + + ks_open_tried = 1; + + DBG("KRT: Opening kernel socket\n"); + + if( (rt_sock = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC)) < 0) + die("Cannot open kernel socket for routes"); + + sk_rt = sk_new(krt_pool); + sk_rt->type = SK_MAGIC; + sk_rt->rx_hook = krt_sock_hook; + sk_rt->fd = rt_sock; + sk_rt->data = x; + if (sk_open(sk_rt)) + bug("krt-sock: sk_open failed"); +} + +void +krt_sys_shutdown(struct krt_proto *x UNUSED, int last UNUSED) { if (!krt_buffer) return; @@ -762,23 +742,14 @@ krt_set_shutdown(struct krt_proto *x UNUSED, int last UNUSED) krt_buffer = NULL; } + void -krt_if_io_init(void) +kif_sys_start(struct kif_proto *p UNUSED) { } void -krt_if_construct(struct kif_config *c UNUSED) -{ -} - -void -krt_if_start(struct kif_proto *p UNUSED) -{ -} - -void -krt_if_shutdown(struct kif_proto *p UNUSED) +kif_sys_shutdown(struct kif_proto *p UNUSED) { if (!kif_buffer) return; diff --git a/sysdep/bsd/krt-sock.h b/sysdep/bsd/krt-sock.h index aab639c4..d9a7ca5d 100644 --- a/sysdep/bsd/krt-sock.h +++ b/sysdep/bsd/krt-sock.h @@ -9,29 +9,10 @@ #ifndef _BIRD_KRT_SOCK_H_ #define _BIRD_KRT_SOCK_H_ -#include -#include -#include "lib/socket.h" - -#ifndef RTAX_MAX -#define RTAX_MAX 8 -#endif - - -struct ks_msg -{ - struct rt_msghdr rtm; - struct sockaddr_storage buf[RTAX_MAX]; +struct krt_params { }; - - -extern int krt_set_sock; - -struct krt_set_params { -}; - -struct krt_set_status { +struct krt_status { }; static inline int krt_set_params_same(struct krt_set_params *o UNUSED, struct krt_set_params *n UNUSED) { return 1; } diff --git a/sysdep/linux/netlink/krt-iface.h b/sysdep/linux/netlink/krt-iface.h index 770c6e2e..8cfe1073 100644 --- a/sysdep/linux/netlink/krt-iface.h +++ b/sysdep/linux/netlink/krt-iface.h @@ -13,17 +13,21 @@ * We don't have split iface/scan/set parts. See krt-scan.h. */ -struct krt_if_params { +struct kif_params { }; -struct krt_if_status { +struct kif_status { }; -static inline void krt_if_construct(struct kif_config *c UNUSED) { }; -static inline void krt_if_shutdown(struct kif_proto *p UNUSED) { }; -static inline void krt_if_io_init(void) { }; -static inline int kif_params_same(struct krt_if_params *old UNUSED, struct krt_if_params *new UNUSED) { return 1; } -static inline void kif_copy_params(struct krt_if_params *dest UNUSED, struct krt_if_params *src UNUSED) { } +static inline void kif_sys_init(struct kif_proto *p UNUSED) { } +static inline int kif_sys_reconfigure(struct kif_proto *p UNUSED, struct kif_config *n UNUSED, struct kif_config *o UNUSED) { return 1; } + +static inline void kif_sys_preconfig(struct config *c UNUSED) { } +static inline void kif_sys_postconfig(struct kif_config *c UNUSED) { } +static inline void kif_sys_init_config(struct kif_config *c UNUSED) { } +static inline void kif_sys_copy_config(struct kif_config *d UNUSED, struct kif_config *s UNUSED) { } + +static inline void kif_sys_io_init(void) { } #endif diff --git a/sysdep/linux/netlink/krt-scan.h b/sysdep/linux/netlink/krt-scan.h index 9b5e075b..302b6093 100644 --- a/sysdep/linux/netlink/krt-scan.h +++ b/sysdep/linux/netlink/krt-scan.h @@ -17,20 +17,14 @@ #define NL_NUM_TABLES 256 -struct krt_scan_params { +struct krt_params { int table_id; /* Kernel table ID we sync with */ }; -struct krt_scan_status { - list temp_ifs; /* Temporary interfaces */ +struct krt_status { }; -static inline int krt_scan_params_same(struct krt_scan_params *o, struct krt_scan_params *n) -{ - return o->table_id == n->table_id; -} -static inline void krt_scan_copy_params(struct krt_scan_params *d UNUSED, struct krt_scan_params *s UNUSED) { } -/* table_id copied in krt_copy_config() */ +static inline void krt_sys_init(struct krt_proto *p UNUSED) { } #endif diff --git a/sysdep/linux/netlink/netlink.Y b/sysdep/linux/netlink/netlink.Y index b00b0eee..51689ff9 100644 --- a/sysdep/linux/netlink/netlink.Y +++ b/sysdep/linux/netlink/netlink.Y @@ -20,7 +20,7 @@ nl_item: KERNEL TABLE expr { if ($3 <= 0 || $3 >= NL_NUM_TABLES) cf_error("Kernel routing table number out of range"); - THIS_KRT->scan.table_id = $3; + THIS_KRT->sys.table_id = $3; } ; diff --git a/sysdep/linux/netlink/netlink.c b/sysdep/linux/netlink/netlink.c index 182088a1..e3faf043 100644 --- a/sysdep/linux/netlink/netlink.c +++ b/sysdep/linux/netlink/netlink.c @@ -548,7 +548,7 @@ nl_parse_addr(struct nlmsghdr *h) } void -krt_if_scan(struct kif_proto *p UNUSED) +kif_do_scan(struct kif_proto *p UNUSED) { struct nlmsghdr *h; @@ -634,7 +634,7 @@ nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int new) r.r.rtm_family = BIRD_AF; r.r.rtm_dst_len = net->n.pxlen; r.r.rtm_tos = 0; - r.r.rtm_table = KRT_CF->scan.table_id; + r.r.rtm_table = KRT_CF->sys.table_id; r.r.rtm_protocol = RTPROT_BIRD; r.r.rtm_scope = RT_SCOPE_UNIVERSE; nl_add_attr_ipa(&r.h, sizeof(r), RTA_DST, net->n.prefix); @@ -687,7 +687,7 @@ nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int new) } void -krt_set_notify(struct krt_proto *p, net *n, rte *new, rte *old, struct ea_list *eattrs) +krt_do_notify(struct krt_proto *p, net *n, rte *new, rte *old, struct ea_list *eattrs) { int err = 0; @@ -940,7 +940,7 @@ nl_parse_route(struct nlmsghdr *h, int scan) } void -krt_scan_fire(struct krt_proto *p UNUSED) /* CONFIG_ALL_TABLES_AT_ONCE => p is NULL */ +krt_do_scan(struct krt_proto *p UNUSED) /* CONFIG_ALL_TABLES_AT_ONCE => p is NULL */ { struct nlmsghdr *h; @@ -1084,36 +1084,9 @@ nl_open_async(void) static u8 nl_cf_table[(NL_NUM_TABLES+7) / 8]; void -krt_scan_preconfig(struct config *c UNUSED) +krt_sys_start(struct krt_proto *p, int first) { - bzero(&nl_cf_table, sizeof(nl_cf_table)); -} - -void -krt_scan_postconfig(struct krt_config *x) -{ - int id = x->scan.table_id; - - if (nl_cf_table[id/8] & (1 << (id%8))) - cf_error("Multiple kernel syncers defined for table #%d", id); - nl_cf_table[id/8] |= (1 << (id%8)); -} - -void -krt_scan_construct(struct krt_config *x) -{ -#ifndef IPV6 - x->scan.table_id = RT_TABLE_MAIN; -#else - x->scan.table_id = 254; -#endif -} - -void -krt_scan_start(struct krt_proto *p, int first) -{ - init_list(&p->scan.temp_ifs); - nl_table_map[KRT_CF->scan.table_id] = p; + nl_table_map[KRT_CF->sys.table_id] = p; if (first) { nl_open(); @@ -1122,13 +1095,55 @@ krt_scan_start(struct krt_proto *p, int first) } void -krt_scan_shutdown(struct krt_proto *p UNUSED, int last UNUSED) +krt_sys_shutdown(struct krt_proto *p UNUSED, int last UNUSED) { } +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; +} + + void -krt_if_start(struct kif_proto *p UNUSED) +krt_sys_preconfig(struct config *c UNUSED) +{ + bzero(&nl_cf_table, sizeof(nl_cf_table)); +} + +void +krt_sys_postconfig(struct krt_config *x) +{ + int id = x->sys.table_id; + + if (nl_cf_table[id/8] & (1 << (id%8))) + cf_error("Multiple kernel syncers defined for table #%d", id); + nl_cf_table[id/8] |= (1 << (id%8)); +} + +void +krt_sys_init_config(struct krt_config *cf) +{ + cf->sys.table_id = RT_TABLE_MAIN; +} + +void +krt_sys_copy_config(struct krt_config *d, struct krt_config *s) +{ + d->sys.table_id = s->sys.table_id; +} + + + +void +kif_sys_start(struct kif_proto *p UNUSED) { nl_open(); nl_open_async(); } + +void +kif_sys_shutdown(struct kif_proto *p UNUSED) +{ +} diff --git a/sysdep/unix/krt-iface.c b/sysdep/unix/krt-iface.c index 69048ae8..88c17ecd 100644 --- a/sysdep/unix/krt-iface.c +++ b/sysdep/unix/krt-iface.c @@ -186,7 +186,7 @@ scan_ifs(struct ifreq *r, int cnt) } void -krt_if_scan(struct kif_proto *p) +kif_do_scan(struct kif_proto *p) { struct ifconf ic; static int last_ifbuf_size = 4*sizeof(struct ifreq); @@ -208,22 +208,17 @@ krt_if_scan(struct kif_proto *p) } void -krt_if_construct(struct kif_config *c) +kif_start(struct kif_proto *p) { } void -krt_if_start(struct kif_proto *p) +kif_shutdown(struct kif_proto *p) { } void -krt_if_shutdown(struct kif_proto *p) -{ -} - -void -krt_if_io_init(void) +kif_io_init(void) { if_scan_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); DBG("Using socket %d for interface and route scanning\n", if_scan_sock); diff --git a/sysdep/unix/krt-iface.h b/sysdep/unix/krt-iface.h index 9e12bcc3..e9e8e507 100644 --- a/sysdep/unix/krt-iface.h +++ b/sysdep/unix/krt-iface.h @@ -9,15 +9,21 @@ #ifndef _BIRD_KRT_IFACE_H_ #define _BIRD_KRT_IFACE_H_ -struct krt_if_params { +struct kif_params { }; -struct krt_if_status { +struct kif_status { }; extern int if_scan_sock; -static inline int kif_params_same(struct krt_if_params *old UNUSED, struct krt_if_params *new UNUSED) { return 1; } -static inline void kif_copy_params(struct krt_if_params *dest UNUSED, struct krt_if_params *src UNUSED) { } + +static inline void kif_sys_init(struct kif_proto *p UNUSED) { } +static inline int kif_sys_reconfigure(struct kif_proto *p UNUSED, struct kif_config *n UNUSED, struct kif_config *o UNUSED) { return 1; } + +static inline void kif_sys_preconfig(struct config *c UNUSED) { } +static inline void kif_sys_postconfig(struct kif_config *c UNUSED) { } +static inline void kif_sys_init_config(struct kif_config *c UNUSED) { } +static inline void kif_sys_copy_config(struct kif_config *d UNUSED, struct kif_config *s UNUSED) { } #endif diff --git a/sysdep/unix/krt-set.c b/sysdep/unix/krt-set.c index 23cbe5c5..252c5d3e 100644 --- a/sysdep/unix/krt-set.c +++ b/sysdep/unix/krt-set.c @@ -79,7 +79,7 @@ krt_ioctl(int ioc, rte *e, char *name) } void -krt_set_notify(struct krt_proto *p, net *net, rte *new, rte *old) +krt_do_notify(struct krt_proto *p, net *net, rte *new, rte *old) { if (old) { @@ -94,18 +94,19 @@ krt_set_notify(struct krt_proto *p, net *net, rte *new, rte *old) } void -krt_set_start(struct krt_proto *x, int first) +krt_sys_start(struct krt_proto *x, int first) { if (if_scan_sock < 0) bug("krt set: missing socket"); } void -krt_set_construct(struct krt_config *c) +krt_sys_shutdown(struct krt_proto *x, int last) +{ +} + +void +krt_sys_construct(struct krt_config *c) { } -void -krt_set_shutdown(struct krt_proto *x, int last) -{ -} diff --git a/sysdep/unix/krt-set.h b/sysdep/unix/krt-set.h index 87cffcfc..8ef3170e 100644 --- a/sysdep/unix/krt-set.h +++ b/sysdep/unix/krt-set.h @@ -1,5 +1,5 @@ /* - * BIRD -- Unix Kernel Route Syncer -- Setting + * BIRD -- Unix Kernel Route Syncer * * (c) 1998--2000 Martin Mares * @@ -9,13 +9,19 @@ #ifndef _BIRD_KRT_SET_H_ #define _BIRD_KRT_SET_H_ -struct krt_set_params { +struct krt_params { }; -struct krt_set_status { +struct krt_status { }; -static inline int krt_set_params_same(struct krt_set_params *o UNUSED, struct krt_set_params *n UNUSED) { return 1; } -static inline void krt_set_copy_params(struct krt_set_params *d UNUSED, struct krt_set_params *s UNUSED) { } + +static inline void krt_sys_init(struct krt_proto *p UNUSED) { } +static inline int krt_sys_reconfigure(struct krt_proto *p UNUSED, struct krt_config *n UNUSED, struct krt_config *o UNUSED) { return 1; } + +static inline void krt_sys_preconfig(struct config *c UNUSED) { } +static inline void krt_sys_postconfig(struct krt_config *c UNUSED) { } +static inline void krt_sys_init_config(struct krt_config *c UNUSED) { } +static inline void krt_sys_copy_config(struct krt_config *d UNUSED, struct krt_config *s UNUSED) { } #endif diff --git a/sysdep/unix/krt.Y b/sysdep/unix/krt.Y index c0141f57..469c136d 100644 --- a/sysdep/unix/krt.Y +++ b/sysdep/unix/krt.Y @@ -25,17 +25,7 @@ CF_GRAMMAR CF_ADDTO(proto, kern_proto '}') -kern_proto_start: proto_start KERNEL { -#ifndef CONFIG_MULTIPLE_TABLES - if (cf_krt) - cf_error("Kernel protocol already defined"); -#endif - cf_krt = this_proto = proto_config_new(&proto_unix_kernel, sizeof(struct krt_config), $1); - THIS_KRT->scan_time = 60; - THIS_KRT->learn = THIS_KRT->persist = 0; - krt_scan_construct(THIS_KRT); - krt_set_construct(THIS_KRT); - } +kern_proto_start: proto_start KERNEL { this_proto = krt_init_config($1); } ; CF_ADDTO(kern_proto, kern_proto_start proto_name '{') @@ -62,14 +52,7 @@ kern_item: CF_ADDTO(proto, kif_proto '}') -kif_proto_start: proto_start DEVICE { - if (cf_kif) - cf_error("Kernel device protocol already defined"); - cf_kif = this_proto = proto_config_new(&proto_unix_iface, sizeof(struct kif_config), $1); - THIS_KIF->scan_time = 60; - init_list(&THIS_KIF->primary); - krt_if_construct(THIS_KIF); - } +kif_proto_start: proto_start DEVICE { this_proto = kif_init_config($1); } ; CF_ADDTO(kif_proto, kif_proto_start proto_name '{') diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index de97a092..cc03bb88 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -66,25 +66,18 @@ krt_io_init(void) { krt_pool = rp_new(&root_pool, "Kernel Syncer"); krt_filter_lp = lp_new(krt_pool, 4080); - krt_if_io_init(); + kif_sys_io_init(); } /* * Interfaces */ -struct proto_config *cf_kif; - +static struct kif_config *kif_cf; static struct kif_proto *kif_proto; static timer *kif_scan_timer; static bird_clock_t kif_last_shot; -static void -kif_preconfig(struct protocol *P UNUSED, struct config *c UNUSED) -{ - cf_kif = NULL; -} - static void kif_scan(timer *t) { @@ -92,7 +85,7 @@ kif_scan(timer *t) KRT_TRACE(p, D_EVENTS, "Scanning interfaces"); kif_last_shot = now; - krt_if_scan(p); + kif_do_scan(p); } static void @@ -112,45 +105,6 @@ kif_request_scan(void) tm_start(kif_scan_timer, 1); } -static struct proto * -kif_init(struct proto_config *c) -{ - struct kif_proto *p = proto_new(c, sizeof(struct kif_proto)); - return &p->p; -} - -static int -kif_start(struct proto *P) -{ - struct kif_proto *p = (struct kif_proto *) P; - - kif_proto = p; - krt_if_start(p); - - /* Start periodic interface scanning */ - kif_scan_timer = tm_new(P->pool); - kif_scan_timer->hook = kif_scan; - kif_scan_timer->data = p; - kif_scan_timer->recurrent = KIF_CF->scan_time; - kif_scan(kif_scan_timer); - tm_start(kif_scan_timer, KIF_CF->scan_time); - - return PS_UP; -} - -static int -kif_shutdown(struct proto *P) -{ - struct kif_proto *p = (struct kif_proto *) P; - - tm_stop(kif_scan_timer); - krt_if_shutdown(p); - kif_proto = NULL; - - return PS_DOWN; -} - - static inline int prefer_scope(struct ifa *a, struct ifa *b) { return (a->scope > SCOPE_LINK) && (b->scope <= SCOPE_LINK); } @@ -193,13 +147,53 @@ kif_choose_primary(struct iface *i) } +static struct proto * +kif_init(struct proto_config *c) +{ + struct kif_proto *p = proto_new(c, sizeof(struct kif_proto)); + + kif_sys_init(p); + return &p->p; +} + +static int +kif_start(struct proto *P) +{ + struct kif_proto *p = (struct kif_proto *) P; + + kif_proto = p; + kif_sys_start(p); + + /* Start periodic interface scanning */ + kif_scan_timer = tm_new(P->pool); + kif_scan_timer->hook = kif_scan; + kif_scan_timer->data = p; + kif_scan_timer->recurrent = KIF_CF->scan_time; + kif_scan(kif_scan_timer); + tm_start(kif_scan_timer, KIF_CF->scan_time); + + return PS_UP; +} + +static int +kif_shutdown(struct proto *P) +{ + struct kif_proto *p = (struct kif_proto *) P; + + tm_stop(kif_scan_timer); + kif_sys_shutdown(p); + kif_proto = NULL; + + return PS_DOWN; +} + static int kif_reconfigure(struct proto *p, struct proto_config *new) { struct kif_config *o = (struct kif_config *) p->cf; struct kif_config *n = (struct kif_config *) new; - if (!kif_params_same(&o->iface, &n->iface)) + if (!kif_sys_reconfigure((struct kif_proto *) p, n, o)) return 0; if (o->scan_time != n->scan_time) @@ -224,6 +218,28 @@ kif_reconfigure(struct proto *p, struct proto_config *new) return 1; } + +static void +kif_preconfig(struct protocol *P UNUSED, struct config *c) +{ + kif_cf = NULL; + kif_sys_preconfig(c); +} + +struct proto_config * +kif_init_config(int class) +{ + if (kif_cf) + cf_error("Kernel device protocol already defined"); + + kif_cf = (struct kif_config *) proto_config_new(&proto_unix_iface, sizeof(struct kif_config), class); + kif_cf->scan_time = 60; + init_list(&kif_cf->primary); + + kif_sys_init_config(kif_cf); + return (struct proto_config *) kif_cf; +} + static void kif_copy_config(struct proto_config *dest, struct proto_config *src) { @@ -231,13 +247,13 @@ kif_copy_config(struct proto_config *dest, struct proto_config *src) struct kif_config *s = (struct kif_config *) src; /* Shallow copy of everything (just scan_time currently) */ - proto_copy_rest(dest, src, sizeof(struct krt_config)); + proto_copy_rest(dest, src, sizeof(struct kif_config)); /* Copy primary addr list */ cfg_copy_list(&d->primary, &s->primary, sizeof(struct kif_primary_item)); /* Fix sysdep parts */ - kif_copy_params(&d->iface, &s->iface); + kif_sys_copy_config(d, s); } @@ -558,7 +574,7 @@ krt_flush_routes(struct krt_proto *p) a->source != RTS_DEVICE && a->source != RTS_INHERIT) { /* FIXME: this does not work if gw is changed in export filter */ - krt_set_notify(p, e->net, NULL, e, NULL); + krt_do_notify(p, e->net, NULL, e, NULL); n->n.flags &= ~KRF_INSTALLED; } } @@ -717,7 +733,7 @@ krt_prune(struct krt_proto *p) if (new && (f->flags & KRF_INSTALLED)) { krt_trace_in(p, new, "reinstalling"); - krt_set_notify(p, n, new, NULL, tmpa); + krt_do_notify(p, n, new, NULL, tmpa); } break; case KRF_SEEN: @@ -726,11 +742,11 @@ krt_prune(struct krt_proto *p) break; case KRF_UPDATE: krt_trace_in(p, new, "updating"); - krt_set_notify(p, n, new, old, tmpa); + krt_do_notify(p, n, new, old, tmpa); break; case KRF_DELETE: krt_trace_in(p, old, "deleting"); - krt_set_notify(p, n, NULL, old, NULL); + krt_do_notify(p, n, NULL, old, NULL); break; default: bug("krt_prune: invalid route status"); @@ -766,7 +782,7 @@ krt_got_route_async(struct krt_proto *p, rte *e, int new) if (new) { krt_trace_in(p, e, "[redirect] deleting"); - krt_set_notify(p, net, NULL, e, NULL); + krt_do_notify(p, net, NULL, e, NULL); } /* If !new, it is probably echo of our deletion */ break; @@ -800,7 +816,7 @@ krt_scan(timer *t UNUSED) p = SKIP_BACK(struct krt_proto, instance_node, HEAD(krt_instance_list)); if (p->instance_node.next) KRT_TRACE(p, D_EVENTS, "Scanning routing table"); - krt_scan_fire(NULL); + krt_do_scan(NULL); WALK_LIST(q, krt_instance_list) { p = SKIP_BACK(struct krt_proto, instance_node, q); @@ -810,14 +826,45 @@ krt_scan(timer *t UNUSED) #else p = t->data; KRT_TRACE(p, D_EVENTS, "Scanning routing table"); - krt_scan_fire(p); + krt_do_scan(p); krt_prune(p); #endif } + /* * Updates */ + +static struct ea_list * +krt_make_tmp_attrs(rte *rt, struct linpool *pool) +{ + struct ea_list *l = lp_alloc(pool, sizeof(struct ea_list) + 2 * sizeof(eattr)); + + l->next = NULL; + l->flags = EALF_SORTED; + l->count = 2; + + l->attrs[0].id = EA_KRT_SOURCE; + l->attrs[0].flags = 0; + l->attrs[0].type = EAF_TYPE_INT | EAF_TEMP; + l->attrs[0].u.data = rt->u.krt.proto; + + l->attrs[1].id = EA_KRT_METRIC; + l->attrs[1].flags = 0; + l->attrs[1].type = EAF_TYPE_INT | EAF_TEMP; + l->attrs[1].u.data = rt->u.krt.metric; + + return l; +} + +static void +krt_store_tmp_attrs(rte *rt, struct ea_list *attrs) +{ + /* EA_KRT_SOURCE is read-only */ + rt->u.krt.metric = ea_get_int(attrs, EA_KRT_METRIC, 0); +} + static int krt_import_control(struct proto *P, rte **new, ea_list **attrs, struct linpool *pool) { @@ -853,37 +900,37 @@ krt_notify(struct proto *P, struct rtable *table UNUSED, net *net, else net->n.flags &= ~KRF_INSTALLED; if (p->initialized) /* Before first scan we don't touch the routes */ - krt_set_notify(p, net, new, old, eattrs); + krt_do_notify(p, net, new, old, eattrs); } +static int +krt_rte_same(rte *a, rte *b) +{ + /* src is always KRT_SRC_ALIEN and type is irrelevant */ + return (a->u.krt.proto == b->u.krt.proto) && (a->u.krt.metric == b->u.krt.metric); +} + + /* * Protocol glue */ -struct proto_config *cf_krt; +struct krt_config *krt_cf; -static void -krt_preconfig(struct protocol *P UNUSED, struct config *c) +static struct proto * +krt_init(struct proto_config *c) { - cf_krt = NULL; - krt_scan_preconfig(c); -} + struct krt_proto *p = proto_new(c, sizeof(struct krt_proto)); -static void -krt_postconfig(struct proto_config *C) -{ - struct krt_config *c = (struct krt_config *) C; + p->p.accept_ra_types = RA_OPTIMAL; + p->p.make_tmp_attrs = krt_make_tmp_attrs; + p->p.store_tmp_attrs = krt_store_tmp_attrs; + p->p.import_control = krt_import_control; + p->p.rt_notify = krt_notify; + p->p.rte_same = krt_rte_same; -#ifdef CONFIG_ALL_TABLES_AT_ONCE - struct krt_config *first = (struct krt_config *) cf_krt; - if (first->scan_time != c->scan_time) - cf_error("All kernel syncers must use the same table scan interval"); -#endif - - if (C->table->krt_attached) - cf_error("Kernel syncer (%s) already attached to table %s", C->table->krt_attached->name, C->table->name); - C->table->krt_attached = C; - krt_scan_postconfig(c); + krt_sys_init(p); + return &p->p; } static timer * @@ -920,8 +967,7 @@ krt_start(struct proto *P) krt_learn_init(p); #endif - krt_scan_start(p, first); - krt_set_start(p, first); + krt_sys_start(p, first); /* Start periodic routing table scanning */ #ifdef CONFIG_ALL_TABLES_AT_ONCE @@ -955,8 +1001,7 @@ krt_shutdown(struct proto *P) if (p->initialized && !KRT_CF->persist) krt_flush_routes(p); - krt_set_shutdown(p, last); - krt_scan_shutdown(p, last); + krt_sys_shutdown(p, last); #ifdef CONFIG_ALL_TABLES_AT_ONCE if (last) @@ -966,69 +1011,55 @@ krt_shutdown(struct proto *P) return PS_DOWN; } -static struct ea_list * -krt_make_tmp_attrs(rte *rt, struct linpool *pool) -{ - struct ea_list *l = lp_alloc(pool, sizeof(struct ea_list) + 2 * sizeof(eattr)); - - l->next = NULL; - l->flags = EALF_SORTED; - l->count = 2; - - l->attrs[0].id = EA_KRT_SOURCE; - l->attrs[0].flags = 0; - l->attrs[0].type = EAF_TYPE_INT | EAF_TEMP; - l->attrs[0].u.data = rt->u.krt.proto; - - l->attrs[1].id = EA_KRT_METRIC; - l->attrs[1].flags = 0; - l->attrs[1].type = EAF_TYPE_INT | EAF_TEMP; - l->attrs[1].u.data = rt->u.krt.metric; - - return l; -} - -static void -krt_store_tmp_attrs(rte *rt, struct ea_list *attrs) -{ - /* EA_KRT_SOURCE is read-only */ - rt->u.krt.metric = ea_get_int(attrs, EA_KRT_METRIC, 0); -} - -static int -krt_rte_same(rte *a, rte *b) -{ - /* src is always KRT_SRC_ALIEN and type is irrelevant */ - return (a->u.krt.proto == b->u.krt.proto) && (a->u.krt.metric == b->u.krt.metric); -} - -static struct proto * -krt_init(struct proto_config *c) -{ - struct krt_proto *p = proto_new(c, sizeof(struct krt_proto)); - - p->p.accept_ra_types = RA_OPTIMAL; - p->p.make_tmp_attrs = krt_make_tmp_attrs; - p->p.store_tmp_attrs = krt_store_tmp_attrs; - p->p.import_control = krt_import_control; - p->p.rt_notify = krt_notify; - p->p.rte_same = krt_rte_same; - - return &p->p; -} - static int krt_reconfigure(struct proto *p, struct proto_config *new) { struct krt_config *o = (struct krt_config *) p->cf; struct krt_config *n = (struct krt_config *) new; - return o->scan_time == n->scan_time - && o->learn == n->learn /* persist needn't be the same */ - && o->devroutes == n->devroutes - && krt_set_params_same(&o->set, &n->set) - && krt_scan_params_same(&o->scan, &n->scan) - ; + if (!krt_sys_reconfigure((struct krt_proto *) p, n, o)) + return 0; + + /* persist needn't be the same */ + return o->scan_time == n->scan_time && o->learn == n->learn && o->devroutes == n->devroutes; +} + +static void +krt_preconfig(struct protocol *P UNUSED, struct config *c) +{ + krt_cf = NULL; + krt_sys_preconfig(c); +} + +static void +krt_postconfig(struct proto_config *C) +{ + struct krt_config *c = (struct krt_config *) C; + +#ifdef CONFIG_ALL_TABLES_AT_ONCE + if (krt_cf->scan_time != c->scan_time) + cf_error("All kernel syncers must use the same table scan interval"); +#endif + + if (C->table->krt_attached) + cf_error("Kernel syncer (%s) already attached to table %s", C->table->krt_attached->name, C->table->name); + C->table->krt_attached = C; + krt_sys_postconfig(c); +} + +struct proto_config * +krt_init_config(int class) +{ +#ifndef CONFIG_MULTIPLE_TABLES + if (krt_cf) + cf_error("Kernel protocol already defined"); +#endif + + krt_cf = (struct krt_config *) proto_config_new(&proto_unix_kernel, sizeof(struct krt_config), class); + krt_cf->scan_time = 60; + + krt_sys_init_config(krt_cf); + return (struct proto_config *) krt_cf; } static void @@ -1041,8 +1072,7 @@ krt_copy_config(struct proto_config *dest, struct proto_config *src) proto_copy_rest(dest, src, sizeof(struct krt_config)); /* Fix sysdep parts */ - krt_set_copy_params(&d->set, &s->set); - krt_scan_copy_params(&d->scan, &s->scan); + krt_sys_copy_config(d, s); } static int diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h index 19b69e49..a3b5658a 100644 --- a/sysdep/unix/krt.h +++ b/sysdep/unix/krt.h @@ -45,8 +45,7 @@ extern struct protocol proto_unix_kernel; struct krt_config { struct proto_config c; - struct krt_set_params set; - struct krt_scan_params scan; + struct krt_params sys; /* Sysdep params */ int persist; /* Keep routes when we exit */ int scan_time; /* How often we re-scan routes */ int learn; /* Learn routes from other sources */ @@ -55,9 +54,7 @@ struct krt_config { struct krt_proto { struct proto p; - struct krt_set_status set; - struct krt_scan_status scan; - struct krt_if_status iface; + struct krt_status sys; /* Sysdep state */ #ifdef KRT_ALLOW_LEARN struct rtable krt_table; /* Internal table of inherited routes */ #endif @@ -69,7 +66,6 @@ struct krt_proto { int initialized; /* First scan has already been finished */ }; -extern struct proto_config *cf_krt; extern pool *krt_pool; #define KRT_CF ((struct krt_config *)p->p.cf) @@ -79,6 +75,7 @@ extern pool *krt_pool; if (pr->p.debug & fl) \ { log(L_TRACE "%s: " msg, pr->p.name , ## args); } } while(0) +struct proto_config * kif_init_config(int class); void kif_request_scan(void); void krt_got_route(struct krt_proto *p, struct rte *e); void krt_got_route_async(struct krt_proto *p, struct rte *e, int new); @@ -101,46 +98,50 @@ struct kif_primary_item { struct kif_config { struct proto_config c; - struct krt_if_params iface; + struct kif_params sys; /* Sysdep params */ int scan_time; /* How often we re-scan interfaces */ list primary; /* Preferences for primary addresses (struct kif_primary_item) */ }; struct kif_proto { struct proto p; - struct krt_if_status iface; + struct kif_status sys; /* Sysdep state */ }; -extern struct proto_config *cf_kif; - #define KIF_CF ((struct kif_config *)p->p.cf) +struct proto_config * krt_init_config(int class); + + /* krt-scan.c */ -void krt_scan_preconfig(struct config *); -void krt_scan_postconfig(struct krt_config *); -void krt_scan_construct(struct krt_config *); -void krt_scan_start(struct krt_proto *, int); -void krt_scan_shutdown(struct krt_proto *, int); +void krt_sys_init(struct krt_proto *); +void krt_sys_start(struct krt_proto *, int); +void krt_sys_shutdown(struct krt_proto *, int); +int krt_sys_reconfigure(struct krt_proto *p UNUSED, struct krt_config *n, struct krt_config *o); -void krt_scan_fire(struct krt_proto *); +void krt_sys_preconfig(struct config *); +void krt_sys_postconfig(struct krt_config *); +void krt_sys_init_config(struct krt_config *); +void krt_sys_copy_config(struct krt_config *, struct krt_config *); -/* krt-set.c */ +int krt_capable(rte *e); +void krt_do_scan(struct krt_proto *); +void krt_do_notify(struct krt_proto *p, net *n, rte *new, rte *old, struct ea_list *eattrs); -void krt_set_construct(struct krt_config *); -void krt_set_start(struct krt_proto *, int); -void krt_set_shutdown(struct krt_proto *, int); - -int krt_capable(rte *e); -void krt_set_notify(struct krt_proto *p, net *n, rte *new, rte *old, struct ea_list *eattrs); /* krt-iface.c */ -void krt_if_construct(struct kif_config *); -void krt_if_start(struct kif_proto *); -void krt_if_shutdown(struct kif_proto *); +void kif_sys_init(struct kif_proto *); +void kif_sys_start(struct kif_proto *); +void kif_sys_shutdown(struct kif_proto *); +int kif_sys_reconfigure(struct kif_proto *, struct kif_config *, struct kif_config *); -void krt_if_scan(struct kif_proto *); -void krt_if_io_init(void); +void kif_sys_init_config(struct kif_config *); +void kif_sys_copy_config(struct kif_config *, struct kif_config *); + +void kif_do_scan(struct kif_proto *); + +// void kif_sys_io_init(void); #endif