Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
BIRD Internet Routing Daemon
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
3
Merge Requests
3
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
labs
BIRD Internet Routing Daemon
Commits
50fe90ed
Commit
50fe90ed
authored
Jan 16, 2000
by
Martin Mareš
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
First attempt on dynamic reconfiguration. There are still lots of bugs
and problems to solve, but the hardest part works.
parent
394aec8f
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
433 additions
and
89 deletions
+433
-89
TODO
TODO
+15
-2
conf/conf.c
conf/conf.c
+115
-6
conf/conf.h
conf/conf.h
+14
-4
doc/reply_codes
doc/reply_codes
+2
-0
nest/proto.c
nest/proto.c
+109
-46
nest/protocol.h
nest/protocol.h
+4
-3
nest/route.h
nest/route.h
+9
-2
nest/rt-table.c
nest/rt-table.c
+59
-8
proto/pipe/pipe.c
proto/pipe/pipe.c
+12
-1
sysdep/unix/config.Y
sysdep/unix/config.Y
+12
-1
sysdep/unix/krt.c
sysdep/unix/krt.c
+9
-1
sysdep/unix/main.c
sysdep/unix/main.c
+71
-14
sysdep/unix/unix.h
sysdep/unix/unix.h
+2
-1
No files found.
TODO
View file @
50fe90ed
...
...
@@ -26,19 +26,21 @@ Core
- config: executable config files
- config: when parsing prefix, check zero bits
- config: reconfiguration
- config: reconfiguration of filters
- config: useless rules when protocols disabled
- config: remove protocol startup priority hacks?
- config: better datetime format
- config: treat shutdown as reconfiguration to null config? (what about config of logging etc. ?)
- config: fix auto_router_id
- krt: rescan interfaces when route addition fails?
- krt: does PERSIST mode have any sense if kernel syncer is shut down as last?
- krt: check behaviour wrt. reconfiguration of routing tables
- tagging of external routes?
- io: use poll if available
- port to FreeBSD
Commands
~~~~~~~~
shutdown # order system shutdown
...
...
@@ -50,6 +52,17 @@ show <name> # show everything you know about symbol <name>
symbols
(disable|enable|restart) <protocol> # or ALL?
- showing of routing table as seen by given protocol
- showing of deleted routing tables and filters
Roadmap
~~~~~~~
- Dynamic reconfiguration
- Allocators and data structures
- Client
- Remaining bits of IPv6 support (radvd)
- RIPv6
- BGP?
- Logging and debugging messages
Client
~~~~~~
...
...
conf/conf.c
View file @
50fe90ed
/*
* BIRD Internet Routing Daemon -- Configuration File Handling
*
* (c) 199
9
Martin Mares <mj@ucw.cz>
* (c) 199
8--2000
Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
...
...
@@ -9,18 +9,22 @@
#include <setjmp.h>
#include <stdarg.h>
#define LOCAL_DEBUG
#include "nest/bird.h"
#include "nest/route.h"
#include "nest/protocol.h"
#include "nest/iface.h"
#include "lib/resource.h"
#include "lib/string.h"
#include "lib/event.h"
#include "conf/conf.h"
#include "filter/filter.h"
static
jmp_buf
conf_jmpbuf
;
struct
config
*
config
,
*
new_config
;
struct
config
*
config
,
*
new_config
,
*
old_config
,
*
future_config
;
static
event
*
config_event
;
struct
config
*
config_alloc
(
byte
*
name
)
...
...
@@ -77,12 +81,117 @@ config_free(struct config *c)
}
void
config_commit
(
struct
config
*
c
)
config_add_obstacle
(
struct
config
*
c
)
{
DBG
(
"+++ adding obstacle %d
\n
"
,
c
->
obstacle_count
);
c
->
obstacle_count
++
;
}
void
config_del_obstacle
(
struct
config
*
c
)
{
DBG
(
"+++ deleting obstacle %d
\n
"
,
c
->
obstacle_count
);
c
->
obstacle_count
--
;
if
(
!
c
->
obstacle_count
)
{
ASSERT
(
config_event
);
ev_schedule
(
config_event
);
}
}
static
int
global_commit
(
struct
config
*
c
,
struct
config
*
old
)
{
if
(
!
old
)
return
0
;
if
(
c
->
router_id
!=
old
->
router_id
)
return
1
;
return
0
;
}
static
int
config_do_commit
(
struct
config
*
c
)
{
int
force_restart
,
nobs
;
DBG
(
"do_commit
\n
"
);
old_config
=
config
;
config
=
c
;
sysdep_commit
(
c
);
rt_commit
(
c
);
protos_commit
(
c
);
if
(
old_config
)
old_config
->
obstacle_count
++
;
DBG
(
"sysdep_commit
\n
"
);
force_restart
=
sysdep_commit
(
c
,
old_config
);
DBG
(
"global_commit
\n
"
);
force_restart
|=
global_commit
(
c
,
old_config
);
DBG
(
"rt_commit
\n
"
);
rt_commit
(
c
,
old_config
);
DBG
(
"protos_commit
\n
"
);
protos_commit
(
c
,
old_config
,
force_restart
);
new_config
=
NULL
;
/* Just to be sure nobody uses that now */
if
(
old_config
)
nobs
=
--
old_config
->
obstacle_count
;
else
nobs
=
0
;
DBG
(
"do_commit finished with %d obstacles remaining
\n
"
,
nobs
);
return
!
nobs
;
}
static
int
config_done
(
void
*
unused
)
{
struct
config
*
c
;
DBG
(
"config_done
\n
"
);
for
(;;)
{
log
(
L_INFO
"Reconfigured"
);
if
(
old_config
)
{
config_free
(
old_config
);
old_config
=
NULL
;
}
if
(
!
future_config
)
break
;
c
=
future_config
;
future_config
=
NULL
;
log
(
L_INFO
"Switching to queued configuration..."
);
if
(
!
config_do_commit
(
c
))
break
;
}
return
0
;
}
int
config_commit
(
struct
config
*
c
)
{
if
(
!
config
)
/* First-time configuration */
{
config_do_commit
(
c
);
return
CONF_DONE
;
}
if
(
old_config
)
/* Reconfiguration already in progress */
{
if
(
future_config
)
{
log
(
L_INFO
"Queueing new configuration, ignoring the one already queued"
);
config_free
(
future_config
);
}
else
log
(
L_INFO
"Queued new configuration"
);
future_config
=
c
;
return
CONF_QUEUED
;
}
if
(
config_do_commit
(
c
))
{
config_done
(
NULL
);
return
CONF_DONE
;
}
if
(
!
config_event
)
{
config_event
=
ev_new
(
&
root_pool
);
config_event
->
hook
=
config_done
;
}
return
CONF_PROGRESS
;
}
void
...
...
conf/conf.h
View file @
50fe90ed
/*
* BIRD Internet Routing Daemon -- Configuration File Handling
*
* (c) 1998--
1999
Martin Mares <mj@ucw.cz>
* (c) 1998--
2000
Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
...
...
@@ -26,17 +26,27 @@ struct config {
char
*
file_name
;
/* Name of configuration file */
struct
symbol
**
sym_hash
;
/* Lexer: symbol hash table */
struct
symbol
**
sym_fallback
;
/* Lexer: fallback symbol hash table */
int
obstacle_count
;
/* Number of items blocking freeing of this config */
};
extern
struct
config
*
config
,
*
new_config
;
/* Please don't use these variables in protocols. Use proto_config->global instead. */
extern
struct
config
*
config
;
/* Currently active configuration */
extern
struct
config
*
new_config
;
/* Configuration being parsed */
extern
struct
config
*
old_config
;
/* Old configuration when reconfiguration is in progress */
extern
struct
config
*
future_config
;
/* New config held here if recon requested during recon */
struct
config
*
config_alloc
(
byte
*
name
);
int
config_parse
(
struct
config
*
);
int
cli_parse
(
struct
config
*
);
void
config_free
(
struct
config
*
);
void
config_commit
(
struct
config
*
);
int
config_commit
(
struct
config
*
);
void
cf_error
(
char
*
msg
,
...)
NORET
;
void
config_add_obstacle
(
struct
config
*
);
void
config_del_obstacle
(
struct
config
*
);
#define CONF_DONE 0
#define CONF_PROGRESS 1
#define CONF_QUEUED 2
/* Pools */
...
...
@@ -87,6 +97,6 @@ int cf_parse(void);
/* Sysdep hooks */
void
sysdep_preconfig
(
struct
config
*
);
void
sysdep_commit
(
struct
config
*
);
int
sysdep_commit
(
struct
config
*
,
struct
config
*
);
#endif
doc/reply_codes
View file @
50fe90ed
...
...
@@ -10,6 +10,7 @@ Reply codes of BIRD command-line interface
0000 OK
0001 Welcome
0002 Reading configuration
1000 BIRD version
1001 Interface list
...
...
@@ -24,6 +25,7 @@ Reply codes of BIRD command-line interface
8000 Reply too long
8001 Route not found
8002 Configuration file error
9000 Command too long
9001 Parse error
...
...
nest/proto.c
View file @
50fe90ed
/*
* BIRD -- Protocols
*
* (c) 1998--
1999
Martin Mares <mj@ucw.cz>
* (c) 1998--
2000
Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
...
...
@@ -38,6 +38,7 @@ static char *p_states[] = { "DOWN", "START", "UP", "STOP" };
static
char
*
c_states
[]
=
{
"HUNGRY"
,
"FEEDING"
,
"HAPPY"
,
"FLUSHING"
};
static
int
proto_flush_all
(
void
*
);
static
void
proto_rethink_goal
(
struct
proto
*
p
);
static
void
proto_enqueue
(
list
*
l
,
struct
proto
*
p
)
...
...
@@ -103,6 +104,7 @@ proto_init_instance(struct proto *p)
p
->
pool
=
rp_new
(
proto_pool
,
p
->
proto
->
name
);
p
->
attn
=
ev_new
(
p
->
pool
);
p
->
attn
->
data
=
p
;
rt_lock_table
(
p
->
table
);
}
struct
announce_hook
*
...
...
@@ -185,42 +187,118 @@ protos_postconfig(struct config *c)
debug
(
"
\n
"
);
}
static
struct
proto
*
proto_init
(
struct
proto_config
*
c
)
{
struct
protocol
*
p
=
c
->
protocol
;
struct
proto
*
q
=
p
->
init
(
c
);
q
->
proto_state
=
PS_DOWN
;
q
->
core_state
=
FS_HUNGRY
;
proto_enqueue
(
&
initial_proto_list
,
q
);
/*
* HACK ALERT! In case of multiple kernel routing tables,
* the kernel syncer acts as multiple protocols which cooperate
* with each other. In order to speed up their initialization,
* we need to know when we're initializing the last one, hence
* the startup counter.
*/
if
(
!
q
->
disabled
)
p
->
startup_counter
++
;
return
q
;
}
void
protos_commit
(
struct
config
*
c
)
protos_commit
(
struct
config
*
new
,
struct
config
*
old
,
int
force_reconfig
)
{
struct
proto_config
*
x
;
struct
protocol
*
p
;
struct
proto
*
q
;
struct
proto_config
*
oc
,
*
nc
;
struct
proto
*
p
,
*
n
;
debug
(
"Protocol commit:
"
);
WALK_LIST
(
x
,
c
->
protos
)
DBG
(
"protos_commit:
\n
"
);
if
(
old
)
{
debug
(
" %s"
,
x
->
name
);
p
=
x
->
protocol
;
q
=
p
->
init
(
x
);
q
->
proto_state
=
PS_DOWN
;
q
->
core_state
=
FS_HUNGRY
;
proto_enqueue
(
&
initial_proto_list
,
q
);
/*
* HACK ALERT! In case of multiple kernel routing tables,
* the kernel syncer acts as multiple protocols which cooperate
* with each other. In order to speed up their initialization,
* we need to know when we're initializing the last one, hence
* the startup counter.
*/
if
(
!
q
->
disabled
)
p
->
startup_counter
++
;
WALK_LIST
(
oc
,
old
->
protos
)
{
struct
proto
*
p
=
oc
->
proto
;
struct
symbol
*
sym
=
cf_find_symbol
(
oc
->
name
);
if
(
sym
&&
sym
->
class
==
SYM_PROTO
)
{
/* Found match, let's check if we can smoothly switch to new configuration */
nc
=
sym
->
def
;
if
(
!
force_reconfig
&&
nc
->
protocol
==
oc
->
protocol
&&
nc
->
preference
==
oc
->
preference
&&
nc
->
disabled
==
oc
->
disabled
&&
nc
->
table
->
table
==
oc
->
table
->
table
&&
nc
->
in_filter
==
oc
->
in_filter
&&
nc
->
out_filter
==
oc
->
out_filter
&&
p
->
proto_state
!=
PS_DOWN
)
{
/* Generic attributes match, try converting them and then ask the protocol */
p
->
debug
=
nc
->
debug
;
if
(
p
->
proto
->
reconfigure
(
p
,
nc
))
{
DBG
(
"
\t
%s: same
\n
"
,
oc
->
name
);
p
->
cf
=
nc
;
nc
->
proto
=
p
;
continue
;
}
}
/* Unsuccessful, force reconfig */
DBG
(
"
\t
%s: power cycling
\n
"
,
oc
->
name
);
p
->
cf_new
=
nc
;
}
else
{
DBG
(
"
\t
%s: deleting
\n
"
,
oc
->
name
);
p
->
cf_new
=
NULL
;
}
p
->
reconfiguring
=
1
;
config_add_obstacle
(
old
);
proto_rethink_goal
(
p
);
}
}
debug
(
"
\n
"
);
WALK_LIST
(
nc
,
new
->
protos
)
if
(
!
nc
->
proto
)
{
DBG
(
"
\t
%s: adding
\n
"
,
nc
->
name
);
proto_init
(
nc
);
}
DBG
(
"
\t
done
\n
"
);
DBG
(
"Protocol start
\n
"
);
WALK_LIST_DELSAFE
(
p
,
n
,
initial_proto_list
)
proto_rethink_goal
(
p
);
}
static
void
proto_rethink_goal
(
struct
proto
*
p
)
{
struct
protocol
*
q
=
p
->
proto
;
struct
protocol
*
q
;
if
(
p
->
reconfiguring
&&
p
->
core_state
==
FS_HUNGRY
&&
p
->
proto_state
==
PS_DOWN
)
{
struct
proto_config
*
nc
=
p
->
cf_new
;
DBG
(
"%s has shut down for reconfiguration
\n
"
,
p
->
name
);
config_del_obstacle
(
p
->
cf
->
global
);
rem_node
(
&
p
->
n
);
mb_free
(
p
);
if
(
!
nc
)
return
;
p
=
proto_init
(
nc
);
/* FIXME: What about protocol priorities??? */
}
/* Determine what state we want to reach */
if
(
p
->
disabled
||
shutting_down
||
p
->
reconfiguring
)
p
->
core_goal
=
FS_HUNGRY
;
else
p
->
core_goal
=
FS_HAPPY
;
if
(
p
->
core_state
==
p
->
core_goal
)
return
;
q
=
p
->
proto
;
if
(
p
->
core_goal
==
FS_HAPPY
)
/* Going up */
{
if
(
p
->
core_state
==
FS_HUNGRY
&&
p
->
proto_state
==
PS_DOWN
)
...
...
@@ -242,25 +320,6 @@ proto_rethink_goal(struct proto *p)
}
}
static
void
proto_set_goal
(
struct
proto
*
p
,
unsigned
goal
)
{
if
(
p
->
disabled
||
shutting_down
)
goal
=
FS_HUNGRY
;
p
->
core_goal
=
goal
;
proto_rethink_goal
(
p
);
}
void
protos_start
(
void
)
{
struct
proto
*
p
,
*
n
;
debug
(
"Protocol start
\n
"
);
WALK_LIST_DELSAFE
(
p
,
n
,
initial_proto_list
)
proto_set_goal
(
p
,
FS_HAPPY
);
}
void
protos_shutdown
(
void
)
{
...
...
@@ -271,12 +330,12 @@ protos_shutdown(void)
if
(
p
->
core_state
!=
FS_HUNGRY
||
p
->
proto_state
!=
PS_DOWN
)
{
proto_shutdown_counter
++
;
proto_
set_goal
(
p
,
FS_HUNGRY
);
proto_
rethink_goal
(
p
);
}
WALK_LIST_BACKWARDS_DELSAFE
(
p
,
n
,
proto_list
)
{
proto_shutdown_counter
++
;
proto_
set_goal
(
p
,
FS_HUNGRY
);
proto_
rethink_goal
(
p
);
}
}
...
...
@@ -329,6 +388,7 @@ static void
proto_fell_down
(
struct
proto
*
p
)
{
DBG
(
"Protocol %s down
\n
"
,
p
->
name
);
rt_unlock_table
(
p
->
table
);
if
(
!--
proto_shutdown_counter
)
protos_shutdown_notify
();
proto_rethink_goal
(
p
);
...
...
@@ -363,7 +423,10 @@ proto_notify_state(struct proto *p, unsigned ps)
{
case
PS_DOWN
:
if
(
cs
==
FS_HUNGRY
)
/* Shutdown finished */
proto_fell_down
(
p
);
{
proto_fell_down
(
p
);
return
;
/* The protocol might have ceased to exist */
}
else
if
(
cs
==
FS_FLUSHING
)
/* Still flushing... */
;
else
/* Need to start flushing */
...
...
nest/protocol.h
View file @
50fe90ed
...
...
@@ -41,7 +41,7 @@ struct protocol {
void
(
*
preconfig
)(
struct
protocol
*
,
struct
config
*
);
/* Just before configuring */
void
(
*
postconfig
)(
struct
proto_config
*
);
/* After configuring each instance */
struct
proto
*
(
*
init
)(
struct
proto_config
*
);
/* Create new instance */
int
(
*
reconfigure
)(
struct
proto
*
,
struct
proto_config
*
);
/* Try to reconfigure instance */
int
(
*
reconfigure
)(
struct
proto
*
,
struct
proto_config
*
);
/* Try to reconfigure instance
, returns success
*/
void
(
*
dump
)(
struct
proto
*
);
/* Debugging dump */
void
(
*
dump_attrs
)(
struct
rte
*
);
/* Dump protocol-dependent attributes */
int
(
*
start
)(
struct
proto
*
);
/* Start the instance */
...
...
@@ -54,8 +54,7 @@ struct protocol {
void
protos_build
(
void
);
void
protos_preconfig
(
struct
config
*
);
void
protos_postconfig
(
struct
config
*
);
void
protos_commit
(
struct
config
*
);
void
protos_start
(
void
);
void
protos_commit
(
struct
config
*
new
,
struct
config
*
old
,
int
force_restart
);
void
protos_dump_all
(
void
);
void
protos_shutdown
(
void
);
...
...
@@ -92,6 +91,7 @@ struct proto {
node
n
;
struct
protocol
*
proto
;
/* Protocol */
struct
proto_config
*
cf
;
/* Configuration data */
struct
proto_config
*
cf_new
;
/* Configuration we want to switch to after shutdown (NULL=delete) */
pool
*
pool
;
/* Pool containing local objects */
struct
event
*
attn
;
/* "Pay attention" event */
...
...
@@ -103,6 +103,7 @@ struct proto {
unsigned
proto_state
;
/* Protocol state machine (see below) */
unsigned
core_state
;
/* Core state machine (see below) */
unsigned
core_goal
;
/* State we want to reach (see below) */
unsigned
reconfiguring
;
/* We're shutting down due to reconfiguration */
bird_clock_t
last_state_change
;
/* Time of last state transition */
/*
...
...
nest/route.h
View file @
50fe90ed
/*
* BIRD Internet Routing Daemon -- Routing Table
*
* (c) 1998--
1999
Martin Mares <mj@ucw.cz>
* (c) 1998--
2000
Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
...
...
@@ -121,6 +121,11 @@ typedef struct rtable {
char
*
name
;
/* Name of this table */
list
hooks
;
/* List of announcement hooks */
int
pipe_busy
;
/* Pipe loop detection */
int
use_count
;
/* Number of protocols using this table */
struct
config
*
deleted
;
/* Table doesn't exist in current configuration,
* delete as soon as use_count becomes 0 and remove
* obstacle from this routing table.
*/
}
rtable
;
typedef
struct
network
{
...
...
@@ -171,7 +176,9 @@ struct config;
void
rt_init
(
void
);
void
rt_preconfig
(
struct
config
*
);
void
rt_commit
(
struct
config
*
);
void
rt_commit
(
struct
config
*
new
,
struct
config
*
old
);
void
rt_lock_table
(
rtable
*
);
void
rt_unlock_table
(
rtable
*
);
void
rt_setup
(
pool
*
,
rtable
*
,
char
*
);
static
inline
net
*
net_find
(
rtable
*
tab
,
ip_addr
addr
,
unsigned
len
)
{
return
(
net
*
)
fib_find
(
&
tab
->
fib
,
&
addr
,
len
);
}
static
inline
net
*
net_get
(
rtable
*
tab
,
ip_addr
addr
,
unsigned
len
)
{
return
(
net
*
)
fib_get
(
&
tab
->
fib
,
&
addr
,
len
);
}
...
...
nest/rt-table.c
View file @
50fe90ed
/*
* BIRD -- Routing Table
*
* (c) 1998--
1999
Martin Mares <mj@ucw.cz>
* (c) 1998--
2000
Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
...
...
@@ -480,17 +480,68 @@ rt_preconfig(struct config *c)
}
void
rt_
commit
(
struct
config
*
c
)
rt_
lock_table
(
rtable
*
r
)
{
struct
rtable_config
*
r
;
r
->
use_count
++
;
}
void
rt_unlock_table
(
rtable
*
r
)
{
if
(
!--
r
->
use_count
&&
r
->
deleted
)
{
struct
config
*
conf
=
r
->
deleted
;
DBG
(
"Deleting routing table %s
\n
"
,
r
->
name
);
rem_node
(
&
r
->
n
);
fib_free
(
&
r
->
fib
);
mb_free
(
r
);
config_del_obstacle
(
conf
);
}
}
void
rt_commit
(
struct
config
*
new
,
struct
config
*
old
)
{
struct
rtable_config
*
o
,
*
r
;
WALK_LIST
(
r
,
c
->
tables
)
DBG
(
"rt_commit:
\n
"
);
if
(
old
)
{
rtable
*
t
=
mb_alloc
(
rt_table_pool
,
sizeof
(
struct
rtable
));
rt_setup
(
rt_table_pool
,
t
,
r
->
name
);
add_tail
(
&
routing_tables
,
&
t
->
n
);
r
->
table
=
t
;
WALK_LIST
(
o
,
old
->
tables
)
{
rtable
*
ot
=
o
->
table
;
if
(
!
ot
->
deleted
)
{
struct
symbol
*
sym
=
cf_find_symbol
(
o
->
name
);
if
(
sym
&&
sym
->
class
==
SYM_TABLE
)
{
DBG
(
"
\t
%s: same
\n
"
,
o
->
name
);
r
=
sym
->
def
;
r
->
table
=
ot
;
ot
->
name
=
r
->
name
;
}
else
{
DBG
(
"
\t
%s: deleted"
,
o
->
name
);
ot
->
deleted
=
old
;
config_add_obstacle
(
old
);
rt_lock_table
(
ot
);
rt_unlock_table
(
ot
);
}
}
}
}
WALK_LIST
(
r
,
new
->
tables
)
if
(
!
r
->
table
)
{
rtable
*
t
=
mb_alloc
(
rt_table_pool
,
sizeof
(
struct
rtable
));
DBG
(
"
\t
%s: created
\n
"
,
r
->
name
);
rt_setup
(
rt_table_pool
,
t
,
r
->
name
);
add_tail
(
&
routing_tables
,
&
t
->
n
);
r
->
table
=
t
;
}
DBG
(
"
\t
done
\n
"
);
}
/*
...
...
proto/pipe/pipe.c
View file @
50fe90ed
/*
* BIRD -- Table-to-Table Routing Protocol a.k.a Pipe
*
* (c) 1999 Martin Mares <mj@ucw.cz>
* (c) 1999
--2000
Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
...
...
@@ -106,10 +106,20 @@ pipe_start(struct proto *P)
*/
a
=
proto_add_announce_hook
(
P
,
p
->
peer
);
a
->
proto
=
&
ph
->
p
;
rt_lock_table
(
p
->
peer
);
return
PS_UP
;
}
static
int
pipe_shutdown
(
struct
proto
*
P
)
{
struct
pipe_proto
*
p
=
(
struct
pipe_proto
*
)
P
;
rt_unlock_table
(
p
->
peer
);
return
PS_DOWN
;
}
static
struct
proto
*
pipe_init
(
struct
proto_config
*
C
)