465bec37c0
Submitted by: maintainer Feature safe: Yes
352 lines
8.2 KiB
Diff
352 lines
8.2 KiB
Diff
Index: sysdep/unix/krt.h
|
|
===================================================================
|
|
--- sysdep/unix/krt.h (revision 4963)
|
|
+++ sysdep/unix/krt.h (revision 4965)
|
|
@@ -67,6 +67,7 @@ struct krt_proto {
|
|
#ifdef CONFIG_ALL_TABLES_AT_ONCE
|
|
node instance_node; /* Node in krt instance list */
|
|
#endif
|
|
+ int rt_sock; /* Routing socket descriptor */
|
|
int initialized; /* First scan has already been finished */
|
|
};
|
|
|
|
Index: sysdep/bsd/krt-sock.h
|
|
===================================================================
|
|
--- sysdep/bsd/krt-sock.h (revision 4963)
|
|
+++ sysdep/bsd/krt-sock.h (revision 4965)
|
|
@@ -42,5 +42,8 @@ struct krt_if_status {
|
|
|
|
static inline int krt_set_params_same(struct krt_set_params *o UNUSED, struct krt_set_params *n UNUSED) { return 1; }
|
|
void krt_read_msg(struct proto *p, struct ks_msg *msg, int scan);
|
|
+int max_fib_num(void);
|
|
+int my_fib_get(void);
|
|
+int my_fib_set(int fib);
|
|
|
|
#endif
|
|
Index: sysdep/bsd/fib.Y
|
|
===================================================================
|
|
--- sysdep/bsd/fib.Y (revision 0)
|
|
+++ sysdep/bsd/fib.Y (revision 4965)
|
|
@@ -0,0 +1,29 @@
|
|
+/*
|
|
+ * BIRD -- FreeBSD rtsock configuration
|
|
+ *
|
|
+ * (c) 2011 Alexander V. Chernikov
|
|
+ *
|
|
+ * Can be freely distributed and used under the terms of the GNU GPL.
|
|
+ */
|
|
+
|
|
+CF_HDR
|
|
+
|
|
+CF_DECLS
|
|
+
|
|
+CF_KEYWORDS(ASYNC, KERNEL, TABLE, KRT_PREFSRC, KRT_REALM)
|
|
+
|
|
+CF_GRAMMAR
|
|
+
|
|
+CF_ADDTO(kern_proto, kern_proto rtsock_item ';')
|
|
+
|
|
+rtsock_item:
|
|
+ KERNEL TABLE expr {
|
|
+ if ($3 < 0 || $3 >= max_fib_num())
|
|
+ cf_error("Kernel routing table number out of range");
|
|
+ THIS_KRT->scan.table_id = $3;
|
|
+ }
|
|
+ ;
|
|
+
|
|
+CF_CODE
|
|
+
|
|
+CF_END
|
|
Index: sysdep/bsd/Modules
|
|
===================================================================
|
|
--- sysdep/bsd/Modules (revision 4963)
|
|
+++ sysdep/bsd/Modules (revision 4965)
|
|
@@ -4,3 +4,4 @@ sysio.h
|
|
krt-set.h
|
|
krt-sock.c
|
|
krt-sock.h
|
|
+fib.Y
|
|
Index: sysdep/bsd/krt-scan.h
|
|
===================================================================
|
|
--- sysdep/bsd/krt-scan.h (revision 4963)
|
|
+++ sysdep/bsd/krt-scan.h (revision 4965)
|
|
@@ -10,6 +10,7 @@
|
|
#define _BIRD_KRT_SCAN_H_
|
|
|
|
struct krt_scan_params {
|
|
+ int table_id; /* Kernel table ID we sync with */
|
|
};
|
|
|
|
struct krt_scan_status {
|
|
Index: sysdep/bsd/krt-sock.c
|
|
===================================================================
|
|
--- sysdep/bsd/krt-sock.c (revision 4963)
|
|
+++ sysdep/bsd/krt-sock.c (revision 4965)
|
|
@@ -33,8 +33,6 @@
|
|
#include "lib/string.h"
|
|
#include "lib/socket.h"
|
|
|
|
-int rt_sock = 0;
|
|
-
|
|
int
|
|
krt_capable(rte *e)
|
|
{
|
|
@@ -53,6 +51,49 @@
|
|
);
|
|
}
|
|
|
|
+int
|
|
+max_fib_num()
|
|
+{
|
|
+ int fibs = 1;
|
|
+ size_t fibs_len = sizeof(fibs);
|
|
+ if (sysctlbyname("net.fibs", &fibs, &fibs_len, NULL, 0) == -1)
|
|
+ {
|
|
+ log(L_ERR "KRT: unable to get fib number, assuming 1. error: %s", strerror(errno));
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ log(L_TRACE "Max fibs: %d", fibs);
|
|
+ return fibs;
|
|
+}
|
|
+
|
|
+int
|
|
+my_fib_get()
|
|
+{
|
|
+ int fib = 0;
|
|
+ size_t fib_len = sizeof(fib);
|
|
+ if (sysctlbyname("net.my_fibnum", &fib, &fib_len, NULL, 0) == -1)
|
|
+ {
|
|
+ log(L_ERR "KRT: unable to get fib number, assuming 0. error: %s", strerror(errno));
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return fib;
|
|
+}
|
|
+
|
|
+int
|
|
+my_fib_set(int fib)
|
|
+{
|
|
+ int old_fib = my_fib_get();
|
|
+
|
|
+ if ((fib != old_fib) && (setfib(fib) == -1))
|
|
+ {
|
|
+ log(L_ERR "KRT: setfib(%d) failed: %s", fib, strerror(errno));
|
|
+ die("Cannot set fib for kernel socket");
|
|
+ }
|
|
+
|
|
+ return old_fib;
|
|
+}
|
|
+
|
|
#define ROUNDUP(a) \
|
|
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
|
|
|
|
@@ -69,7 +110,7 @@
|
|
body += l;}
|
|
|
|
static int
|
|
-krt_sock_send(int cmd, rte *e)
|
|
+krt_sock_send(struct krt_proto *p, int cmd, rte *e)
|
|
{
|
|
net *net = e->net;
|
|
rta *a = e->attrs;
|
|
@@ -180,7 +221,7 @@
|
|
l = body - (char *)&msg;
|
|
msg.rtm.rtm_msglen = l;
|
|
|
|
- if ((l = write(rt_sock, (char *)&msg, l)) < 0) {
|
|
+ if ((l = write(p->rt_sock, (char *)&msg, l)) < 0) {
|
|
log(L_ERR "KRT: Error sending route %I/%d to kernel: %m", net->n.prefix, net->n.pxlen);
|
|
return -1;
|
|
}
|
|
@@ -189,15 +230,15 @@
|
|
}
|
|
|
|
void
|
|
-krt_set_notify(struct krt_proto *p UNUSED, net *n, rte *new, rte *old)
|
|
+krt_set_notify(struct krt_proto *p, net *n, rte *new, rte *old)
|
|
{
|
|
int err = 0;
|
|
|
|
if (old)
|
|
- krt_sock_send(RTM_DELETE, old);
|
|
+ krt_sock_send(p, RTM_DELETE, old);
|
|
|
|
if (new)
|
|
- err = krt_sock_send(RTM_ADD, new);
|
|
+ err = krt_sock_send(p, RTM_ADD, new);
|
|
|
|
if (err < 0)
|
|
n->n.flags |= KRF_SYNC_ERROR;
|
|
@@ -223,25 +264,34 @@
|
|
krt_set_start(struct krt_proto *x, int first UNUSED)
|
|
{
|
|
sock *sk_rt;
|
|
- static int ks_open_tried = 0;
|
|
+ struct krt_config *c;
|
|
+ int fib = 0, old_fib = 0;
|
|
|
|
- if (ks_open_tried)
|
|
- return;
|
|
-
|
|
- ks_open_tried = 1;
|
|
+ if (!strcmp(x->p.proto->name, "Kernel"))
|
|
+ {
|
|
+ c = (struct krt_config *)x->p.cf;
|
|
+ fib = c->scan.table_id;
|
|
|
|
- DBG("KRT: Opening kernel socket\n");
|
|
+ DBG("KRT: Opening kernel route socket to fib %d\n", fib);
|
|
+ if (x->p.debug & D_ROUTES)
|
|
+ log(L_TRACE "Opening route socket to fib %d", fib);
|
|
|
|
- if( (rt_sock = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC)) < 0)
|
|
+ old_fib = my_fib_set(fib);
|
|
+ }
|
|
+
|
|
+ if( (x->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->fd = x->rt_sock;
|
|
sk_rt->data = x;
|
|
if (sk_open(sk_rt))
|
|
bug("krt-sock: sk_open failed");
|
|
+
|
|
+ /* Rollback fib */
|
|
+ my_fib_set(old_fib);
|
|
}
|
|
|
|
#define SKIP(ARG...) do { DBG("KRT: Ignoring route - " ARG); return; } while(0)
|
|
@@ -629,6 +679,8 @@
|
|
size_t obl, needed;
|
|
struct ks_msg *m;
|
|
int retries = 3;
|
|
+ struct krt_config *c;
|
|
+ int fib = 0, old_fib = 0;
|
|
|
|
mib[0] = CTL_NET;
|
|
mib[1] = PF_ROUTE;
|
|
@@ -637,6 +689,17 @@
|
|
mib[4] = cmd;
|
|
mib[5] = 0;
|
|
|
|
+ if (!strcmp(p->proto->name, "Kernel"))
|
|
+ {
|
|
+ c = (struct krt_config *)p->cf;
|
|
+ fib = c->scan.table_id;
|
|
+
|
|
+ DBG("KRT: Setting fib to %d for route dump\n", fib);
|
|
+ if (p->debug & D_ROUTES)
|
|
+ log(L_TRACE "Setting fib to %d for route dump", fib);
|
|
+
|
|
+ old_fib = my_fib_set(fib);
|
|
+ }
|
|
try:
|
|
if (sysctl(mib, 6 , NULL , &needed, NULL, 0) < 0)
|
|
die("krt_sysctl_scan 1: %m");
|
|
@@ -661,6 +724,7 @@
|
|
goto try;
|
|
|
|
log(L_ERR "KRT: Route scan failed");
|
|
+ my_fib_set(old_fib);
|
|
return;
|
|
}
|
|
die("krt_sysctl_scan 2: %m");
|
|
@@ -671,6 +735,8 @@
|
|
m = (struct ks_msg *)next;
|
|
krt_read_msg(p, m, 1);
|
|
}
|
|
+
|
|
+ my_fib_set(old_fib);
|
|
}
|
|
|
|
static byte *krt_buffer = NULL;
|
|
@@ -700,13 +766,16 @@
|
|
}
|
|
|
|
void
|
|
-krt_set_shutdown(struct krt_proto *x UNUSED, int last UNUSED)
|
|
+krt_set_shutdown(struct krt_proto *x UNUSED, int last)
|
|
{
|
|
if (!krt_buffer)
|
|
return;
|
|
|
|
- mb_free(krt_buffer);
|
|
- krt_buffer = NULL;
|
|
+ if (last)
|
|
+ {
|
|
+ mb_free(krt_buffer);
|
|
+ krt_buffer = NULL;
|
|
+ }
|
|
}
|
|
|
|
void
|
|
Index: sysdep/cf/bsd-v6.h
|
|
===================================================================
|
|
--- sysdep/cf/bsd-v6.h (revision 4963)
|
|
+++ sysdep/cf/bsd-v6.h (revision 4965)
|
|
@@ -10,7 +10,7 @@
|
|
|
|
#define CONFIG_AUTO_ROUTES
|
|
#define CONFIG_SELF_CONSCIOUS
|
|
-#undef CONFIG_MULTIPLE_TABLES
|
|
+#define CONFIG_MULTIPLE_TABLES
|
|
|
|
#undef CONFIG_UNIX_IFACE
|
|
#undef CONFIG_UNIX_SET
|
|
Index: sysdep/cf/bsd.h
|
|
===================================================================
|
|
--- sysdep/cf/bsd.h (revision 4963)
|
|
+++ sysdep/cf/bsd.h (revision 4965)
|
|
@@ -8,7 +8,7 @@
|
|
|
|
#define CONFIG_AUTO_ROUTES
|
|
#define CONFIG_SELF_CONSCIOUS
|
|
-#undef CONFIG_MULTIPLE_TABLES
|
|
+#define CONFIG_MULTIPLE_TABLES
|
|
|
|
#undef CONFIG_UNIX_IFACE
|
|
#undef CONFIG_UNIX_SET
|
|
Index: sysdep/unix/krt.c
|
|
===================================================================
|
|
--- sysdep/unix/krt.c (revision 4966)
|
|
+++ sysdep/unix/krt.c (revision 4967)
|
|
@@ -492,9 +492,9 @@
|
|
|
|
#ifdef CONFIG_ALL_TABLES_AT_ONCE
|
|
static timer *krt_scan_timer;
|
|
-static int krt_instance_count;
|
|
static list krt_instance_list;
|
|
#endif
|
|
+static int krt_instance_count;
|
|
|
|
static void
|
|
krt_flush_routes(struct krt_proto *p)
|
|
@@ -830,6 +830,7 @@
|
|
add_tail(&krt_instance_list, &p->instance_node);
|
|
#else
|
|
p->krt_pool = P->pool;
|
|
+ krt_instance_count++;
|
|
#endif
|
|
|
|
#ifdef KRT_ALLOW_LEARN
|
|
@@ -859,11 +860,12 @@
|
|
struct krt_proto *p = (struct krt_proto *) P;
|
|
int last = 1;
|
|
|
|
+ if (--krt_instance_count)
|
|
+ last = 0;
|
|
+
|
|
#ifdef CONFIG_ALL_TABLES_AT_ONCE
|
|
rem_node(&p->instance_node);
|
|
- if (--krt_instance_count)
|
|
- last = 0;
|
|
- else
|
|
+ if (!krt_instance_count)
|
|
#endif
|
|
tm_stop(p->scan_timer);
|
|
|