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
b662290f
Commit
b662290f
authored
Jan 10, 2013
by
Ondřej Zajíček
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Separate import and receive limits.
They have different behavior w.r.t. filtered routes that are kept.
parent
79b4e12e
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
94 additions
and
22 deletions
+94
-22
README
README
+1
-1
doc/bird.sgml
doc/bird.sgml
+14
-6
nest/config.Y
nest/config.Y
+2
-1
nest/proto.c
nest/proto.c
+15
-6
nest/protocol.h
nest/protocol.h
+12
-3
nest/rt-table.c
nest/rt-table.c
+44
-5
proto/bgp/bgp.c
proto/bgp/bgp.c
+1
-0
proto/pipe/pipe.c
proto/pipe/pipe.c
+5
-0
No files found.
README
View file @
b662290f
...
...
@@ -3,7 +3,7 @@
(c) 1998--2008 Martin Mares <mj@ucw.cz>
(c) 1998--2000 Pavel Machek <pavel@ucw.cz>
(c) 1998--2008 Ondrej Filip <feela@network.cz>
(c) 2009--201
1
CZ.NIC z.s.p.o.
(c) 2009--201
3
CZ.NIC z.s.p.o.
================================================================================
...
...
doc/bird.sgml
View file @
b662290f
...
...
@@ -482,15 +482,23 @@ to zero to disable it. An empty <cf><m/switch/</cf> is equivalent to <cf/on/
Specify an import route limit (a maximum number of routes
imported from the protocol) and optionally the action to be
taken when the limit is hit. Warn action just prints warning
log message. Block action
ignore
s new routes coming from the
log message. Block action
discard
s new routes coming from the
protocol. Restart and disable actions shut the protocol down
like appropriate commands. Disable is the default action if an
action is not explicitly specified. Note that limits are reset
during protocol reconfigure, reload or restart. Also note that
if <cf/import keep filtered/ is active, filtered routes are
counted towards the limit and blocked routes are forgotten, as
the main purpose of the import limit is to protect routing
tables from overflow. Default: <cf/none/.
during protocol reconfigure, reload or restart. Default: <cf/none/.
<tag>receive limit <m/number/ [action warn | block | restart | disable]</tag>
Specify an receive route limit (a maximum number of routes
received from the protocol and remembered). It works almost
identically to <cf>import limit</cf> option, the only
difference is that if <cf/import keep filtered/ option is
active, filtered routes are counted towards the limit and
blocked routes are forgotten, as the main purpose of the
receive limit is to protect routing tables from
overflow. Import limit, on the contrary, counts accepted
routes only and routes blocked by the limit are handled like
filtered routes. Default: <cf/none/.
<tag>export limit <m/number/ [action warn | block | restart | disable]</tag>
Specify an export route limit, works similarly to
...
...
nest/config.Y
View file @
b662290f
...
...
@@ -44,7 +44,7 @@ CF_DECLS
CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
CF_KEYWORDS(LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
CF_KEYWORDS(
RECEIVE,
LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE, ROA, MAX, FLUSH)
CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION, SORTED)
...
...
@@ -185,6 +185,7 @@ proto_item:
| MRTDUMP mrtdump_mask { this_proto->mrtdump = $2; }
| IMPORT imexport { this_proto->in_filter = $2; }
| EXPORT imexport { this_proto->out_filter = $2; }
| RECEIVE LIMIT limit_spec { this_proto->rx_limit = $3; }
| IMPORT LIMIT limit_spec { this_proto->in_limit = $3; }
| EXPORT LIMIT limit_spec { this_proto->out_limit = $3; }
| IMPORT KEEP FILTERED bool { this_proto->in_keep_filtered = $4; }
...
...
nest/proto.c
View file @
b662290f
...
...
@@ -344,6 +344,7 @@ protos_postconfig(struct config *c)
WALK_LIST
(
x
,
c
->
protos
)
{
DBG
(
" %s"
,
x
->
name
);
p
=
x
->
protocol
;
if
(
p
->
postconfig
)
p
->
postconfig
(
x
);
...
...
@@ -410,6 +411,7 @@ proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config
{
p
->
main_ahook
->
in_filter
=
nc
->
in_filter
;
p
->
main_ahook
->
out_filter
=
nc
->
out_filter
;
p
->
main_ahook
->
rx_limit
=
nc
->
rx_limit
;
p
->
main_ahook
->
in_limit
=
nc
->
in_limit
;
p
->
main_ahook
->
out_limit
=
nc
->
out_limit
;
p
->
main_ahook
->
in_keep_filtered
=
nc
->
in_keep_filtered
;
...
...
@@ -804,9 +806,11 @@ proto_schedule_feed(struct proto *p, int initial)
p
->
main_ahook
=
proto_add_announce_hook
(
p
,
p
->
table
,
&
p
->
stats
);
p
->
main_ahook
->
in_filter
=
p
->
cf
->
in_filter
;
p
->
main_ahook
->
out_filter
=
p
->
cf
->
out_filter
;
p
->
main_ahook
->
rx_limit
=
p
->
cf
->
rx_limit
;
p
->
main_ahook
->
in_limit
=
p
->
cf
->
in_limit
;
p
->
main_ahook
->
out_limit
=
p
->
cf
->
out_limit
;
p
->
main_ahook
->
in_keep_filtered
=
p
->
cf
->
in_keep_filtered
;
proto_reset_limit
(
p
->
main_ahook
->
rx_limit
);
proto_reset_limit
(
p
->
main_ahook
->
in_limit
);
proto_reset_limit
(
p
->
main_ahook
->
out_limit
);
}
...
...
@@ -978,6 +982,7 @@ proto_limit_name(struct proto_limit *l)
* proto_notify_limit: notify about limit hit and take appropriate action
* @ah: announce hook
* @l: limit being hit
* @dir: limit direction (PLD_*)
* @rt_count: the number of routes
*
* The function is called by the route processing core when limit @l
...
...
@@ -985,10 +990,11 @@ proto_limit_name(struct proto_limit *l)
* according to @l->action.
*/
void
proto_notify_limit
(
struct
announce_hook
*
ah
,
struct
proto_limit
*
l
,
u32
rt_count
)
proto_notify_limit
(
struct
announce_hook
*
ah
,
struct
proto_limit
*
l
,
int
dir
,
u32
rt_count
)
{
const
char
*
dir_name
[
PLD_MAX
]
=
{
"receive"
,
"import"
,
"export"
};
const
byte
dir_down
[
PLD_MAX
]
=
{
PDC_RX_LIMIT_HIT
,
PDC_IN_LIMIT_HIT
,
PDC_OUT_LIMIT_HIT
};
struct
proto
*
p
=
ah
->
proto
;
int
dir
=
(
ah
->
in_limit
==
l
);
if
(
l
->
state
==
PLS_BLOCKED
)
return
;
...
...
@@ -996,7 +1002,7 @@ proto_notify_limit(struct announce_hook *ah, struct proto_limit *l, u32 rt_count
/* For warning action, we want the log message every time we hit the limit */
if
(
!
l
->
state
||
((
l
->
action
==
PLA_WARN
)
&&
(
rt_count
==
l
->
limit
)))
log
(
L_WARN
"Protocol %s hits route %s limit (%d), action: %s"
,
p
->
name
,
dir
?
"import"
:
"export"
,
l
->
limit
,
proto_limit_name
(
l
));
p
->
name
,
dir
_name
[
dir
]
,
l
->
limit
,
proto_limit_name
(
l
));
switch
(
l
->
action
)
{
...
...
@@ -1011,8 +1017,7 @@ proto_notify_limit(struct announce_hook *ah, struct proto_limit *l, u32 rt_count
case
PLA_RESTART
:
case
PLA_DISABLE
:
l
->
state
=
PLS_BLOCKED
;
proto_schedule_down
(
p
,
l
->
action
==
PLA_RESTART
,
dir
?
PDC_IN_LIMIT_HIT
:
PDC_OUT_LIMIT_HIT
);
proto_schedule_down
(
p
,
l
->
action
==
PLA_RESTART
,
dir_down
[
dir
]);
break
;
}
}
...
...
@@ -1146,6 +1151,7 @@ proto_show_basic_info(struct proto *p)
cli_msg
(
-
1006
,
" Input filter: %s"
,
filter_name
(
p
->
cf
->
in_filter
));
cli_msg
(
-
1006
,
" Output filter: %s"
,
filter_name
(
p
->
cf
->
out_filter
));
proto_show_limit
(
p
->
cf
->
rx_limit
,
"Receive limit:"
);
proto_show_limit
(
p
->
cf
->
in_limit
,
"Import limit:"
);
proto_show_limit
(
p
->
cf
->
out_limit
,
"Export limit:"
);
...
...
@@ -1267,7 +1273,10 @@ proto_cmd_reload(struct proto *p, unsigned int dir, int cnt UNUSED)
* Perhaps, but these hooks work asynchronously.
*/
if
(
!
p
->
proto
->
multitable
)
proto_reset_limit
(
p
->
main_ahook
->
in_limit
);
{
proto_reset_limit
(
p
->
main_ahook
->
rx_limit
);
proto_reset_limit
(
p
->
main_ahook
->
in_limit
);
}
}
/* re-exporting routes */
...
...
nest/protocol.h
View file @
b662290f
...
...
@@ -95,6 +95,8 @@ struct proto_config {
u32
router_id
;
/* Protocol specific router ID */
struct
rtable_config
*
table
;
/* Table we're attached to */
struct
filter
*
in_filter
,
*
out_filter
;
/* Attached filters */
struct
proto_limit
*
rx_limit
;
/* Limit for receiving routes from protocol
(relevant when in_keep_filtered is active) */
struct
proto_limit
*
in_limit
;
/* Limit for importing routes from protocol */
struct
proto_limit
*
out_limit
;
/* Limit for exporting routes to protocol */
...
...
@@ -225,8 +227,9 @@ struct proto_spec {
#define PDC_CMD_DISABLE 0x11
/* Result of disable command */
#define PDC_CMD_RESTART 0x12
/* Result of restart command */
#define PDC_CMD_SHUTDOWN 0x13
/* Result of global shutdown */
#define PDC_IN_LIMIT_HIT 0x21
/* Route import limit reached */
#define PDC_OUT_LIMIT_HIT 0x22
/* Route export limit reached */
#define PDC_RX_LIMIT_HIT 0x21
/* Route receive limit reached */
#define PDC_IN_LIMIT_HIT 0x22
/* Route import limit reached */
#define PDC_OUT_LIMIT_HIT 0x23
/* Route export limit reached */
void
*
proto_new
(
struct
proto_config
*
,
unsigned
size
);
...
...
@@ -373,6 +376,11 @@ extern struct proto_config *cf_dev_proto;
* Protocol limits
*/
#define PLD_RX 0
/* Receive limit */
#define PLD_IN 1
/* Import limit */
#define PLD_OUT 2
/* Export limit */
#define PLD_MAX 3
#define PLA_WARN 1
/* Issue log warning */
#define PLA_BLOCK 2
/* Block new routes */
#define PLA_RESTART 4
/* Force protocol restart */
...
...
@@ -388,7 +396,7 @@ struct proto_limit {
byte
state
;
/* State of limit (PLS_*) */
};
void
proto_notify_limit
(
struct
announce_hook
*
ah
,
struct
proto_limit
*
l
,
u32
rt_count
);
void
proto_notify_limit
(
struct
announce_hook
*
ah
,
struct
proto_limit
*
l
,
int
dir
,
u32
rt_count
);
static
inline
void
proto_reset_limit
(
struct
proto_limit
*
l
)
...
...
@@ -408,6 +416,7 @@ struct announce_hook {
struct
proto
*
proto
;
struct
filter
*
in_filter
;
/* Input filter */
struct
filter
*
out_filter
;
/* Output filter */
struct
proto_limit
*
rx_limit
;
/* Receive limit (for in_keep_filtered) */
struct
proto_limit
*
in_limit
;
/* Input limit */
struct
proto_limit
*
out_limit
;
/* Output limit */
struct
proto_stats
*
stats
;
/* Per-table protocol statistics */
...
...
nest/rt-table.c
View file @
b662290f
...
...
@@ -285,7 +285,7 @@ do_rt_notify(struct announce_hook *ah, net *net, rte *new, rte *old, ea_list *tm
if
(
l
&&
new
)
{
if
((
!
old
||
refeed
)
&&
(
stats
->
exp_routes
>=
l
->
limit
))
proto_notify_limit
(
ah
,
l
,
stats
->
exp_routes
);
proto_notify_limit
(
ah
,
l
,
PLD_OUT
,
stats
->
exp_routes
);
if
(
l
->
state
==
PLS_BLOCKED
)
{
...
...
@@ -700,16 +700,22 @@ rte_recalculate(struct announce_hook *ah, net *net, rte *new, ea_list *tmpa, str
return
;
}
struct
proto_limit
*
l
=
ah
->
in_limit
;
int
new_ok
=
rte_is_ok
(
new
);
int
old_ok
=
rte_is_ok
(
old
);
struct
proto_limit
*
l
=
ah
->
rx_limit
;
if
(
l
&&
!
old
&&
new
)
{
u32
all_routes
=
stats
->
imp_routes
+
stats
->
filt_routes
;
if
(
all_routes
>=
l
->
limit
)
proto_notify_limit
(
ah
,
l
,
all_routes
);
proto_notify_limit
(
ah
,
l
,
PLD_RX
,
all_routes
);
if
(
l
->
state
==
PLS_BLOCKED
)
{
/* In receive limit the situation is simple, old is NULL so
we just free new and exit like nothing happened */
stats
->
imp_updates_ignored
++
;
rte_trace_in
(
D_FILTERS
,
p
,
new
,
"ignored [limit]"
);
rte_free_quick
(
new
);
...
...
@@ -717,8 +723,39 @@ rte_recalculate(struct announce_hook *ah, net *net, rte *new, ea_list *tmpa, str
}
}
int
new_ok
=
rte_is_ok
(
new
);
int
old_ok
=
rte_is_ok
(
old
);
l
=
ah
->
in_limit
;
if
(
l
&&
!
old_ok
&&
new_ok
)
{
if
(
stats
->
imp_routes
>=
l
->
limit
)
proto_notify_limit
(
ah
,
l
,
PLD_IN
,
stats
->
imp_routes
);
if
(
l
->
state
==
PLS_BLOCKED
)
{
/* In import limit the situation is more complicated. We
shouldn't just drop the route, we should handle it like
it was filtered. We also have to continue the route
processing if old or new is non-NULL, but we should exit
if both are NULL as this case is probably assumed to be
already handled. */
stats
->
imp_updates_ignored
++
;
rte_trace_in
(
D_FILTERS
,
p
,
new
,
"ignored [limit]"
);
if
(
ah
->
in_keep_filtered
)
new
->
flags
|=
REF_FILTERED
;
else
{
rte_free_quick
(
new
);
new
=
NULL
;
}
/* Note that old && !new could be possible when
ah->in_keep_filtered changed in the recent past. */
if
(
!
old
&&
!
new
)
return
;
new_ok
=
0
;
goto
skip_stats1
;
}
}
if
(
new_ok
)
stats
->
imp_updates_accepted
++
;
...
...
@@ -727,6 +764,8 @@ rte_recalculate(struct announce_hook *ah, net *net, rte *new, ea_list *tmpa, str
else
stats
->
imp_withdraws_ignored
++
;
skip_stats1:
if
(
new
)
rte_is_filtered
(
new
)
?
stats
->
filt_routes
++
:
stats
->
imp_routes
++
;
if
(
old
)
...
...
proto/bgp/bgp.c
View file @
b662290f
...
...
@@ -878,6 +878,7 @@ bgp_shutdown(struct proto *P)
subcode
=
4
;
// Errcode 6, 4 - administrative reset
break
;
case
PDC_RX_LIMIT_HIT
:
case
PDC_IN_LIMIT_HIT
:
subcode
=
1
;
// Errcode 6, 1 - max number of prefixes reached
/* log message for compatibility */
...
...
proto/pipe/pipe.c
View file @
b662290f
...
...
@@ -200,6 +200,11 @@ pipe_postconfig(struct proto_config *C)
cf_error
(
"Name of peer routing table not specified"
);
if
(
c
->
peer
==
C
->
table
)
cf_error
(
"Primary table and peer table must be different"
);
if
(
C
->
in_keep_filtered
)
cf_error
(
"Pipe protocol prohibits keeping filtered routes"
);
if
(
C
->
rx_limit
)
cf_error
(
"Pipe protocol does not support receive limits"
);
}
extern
int
proto_reconfig_type
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment