diff options
-rw-r--r-- | usr.sbin/bgpd/bgpd.conf.5 | 18 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 5 | ||||
-rw-r--r-- | usr.sbin/bgpd/parse.y | 62 | ||||
-rw-r--r-- | usr.sbin/bgpd/printconf.c | 8 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_filter.c | 33 |
5 files changed, 121 insertions, 5 deletions
diff --git a/usr.sbin/bgpd/bgpd.conf.5 b/usr.sbin/bgpd/bgpd.conf.5 index 16c3dde98ba..56ae9661be5 100644 --- a/usr.sbin/bgpd/bgpd.conf.5 +++ b/usr.sbin/bgpd/bgpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bgpd.conf.5,v 1.43 2005/03/11 12:54:19 claudio Exp $ +.\" $OpenBSD: bgpd.conf.5,v 1.44 2005/03/14 17:32:04 claudio Exp $ .\" .\" Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> .\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -812,11 +812,27 @@ or Set the .Em LOCAL_PREF AS path attribute. +If +.Ar number +starts with a sign +.Em LOCAL_PREF +will be adjusted by adding or substracting +.Ar number +else it will be set to +.Ar number . .Pp .It Ic med Ar number Set the .Em MULTI_EXIT_DISC AS path attribute. +If +.Ar number +starts with a sign +.Em MULTI_EXIT_DISC +will be adjusted by adding or substracting +.Ar number +else it will be set to +.Ar number . .Pp .It Xo .Ic nexthop diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 362a2026167..b03e88f7501 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.157 2005/03/14 12:25:50 henning Exp $ */ +/* $OpenBSD: bgpd.h,v 1.158 2005/03/14 17:32:04 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -540,7 +540,9 @@ struct filter_rule { enum action_types { ACTION_SET_LOCALPREF, + ACTION_SET_RELATIVE_LOCALPREF, ACTION_SET_MED, + ACTION_SET_RELATIVE_MED, ACTION_SET_PREPEND_SELF, ACTION_SET_PREPEND_PEER, ACTION_SET_NEXTHOP, @@ -557,6 +559,7 @@ struct filter_set { union { u_int8_t prepend; u_int32_t metric; + int32_t relative; struct bgpd_addr nexthop; struct filter_community community; char pftable[PFTABLE_LEN]; diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index 8e3ef2cf638..8e13288efcb 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.151 2005/03/13 15:27:30 henning Exp $ */ +/* $OpenBSD: parse.y,v 1.152 2005/03/14 17:32:04 claudio Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -1134,18 +1134,78 @@ filter_set_opt : LOCALPREF number { $$->type = ACTION_SET_LOCALPREF; $$->action.metric = $2; } + | LOCALPREF '+' number { + if ($3 > INT_MAX) { + yyerror("metric to small: max %u", INT_MAX); + YYERROR; + } + if (($$ = calloc(1, sizeof(struct filter_set))) == NULL) + fatal(NULL); + $$->type = ACTION_SET_RELATIVE_LOCALPREF; + $$->action.relative = $3; + } + | LOCALPREF '-' number { + if ($3 > INT_MAX) { + yyerror("metric to small: min -%u", INT_MAX); + YYERROR; + } + if (($$ = calloc(1, sizeof(struct filter_set))) == NULL) + fatal(NULL); + $$->type = ACTION_SET_RELATIVE_LOCALPREF; + $$->action.relative = -$3; + } | MED number { if (($$ = calloc(1, sizeof(struct filter_set))) == NULL) fatal(NULL); $$->type = ACTION_SET_MED; $$->action.metric = $2; } + | MED '+' number { + if ($3 > INT_MAX) { + yyerror("metric to small: max %u", INT_MAX); + YYERROR; + } + if (($$ = calloc(1, sizeof(struct filter_set))) == NULL) + fatal(NULL); + $$->type = ACTION_SET_RELATIVE_MED; + $$->action.metric = $3; + } + | MED '-' number { + if ($3 > INT_MAX) { + yyerror("metric to small: min -%u", INT_MAX); + YYERROR; + } + if (($$ = calloc(1, sizeof(struct filter_set))) == NULL) + fatal(NULL); + $$->type = ACTION_SET_RELATIVE_MED; + $$->action.relative = -$3; + } | METRIC number { /* alias for MED */ if (($$ = calloc(1, sizeof(struct filter_set))) == NULL) fatal(NULL); $$->type = ACTION_SET_MED; $$->action.metric = $2; } + | METRIC '+' number { + if ($3 > INT_MAX) { + yyerror("metric to small: max %u", INT_MAX); + YYERROR; + } + if (($$ = calloc(1, sizeof(struct filter_set))) == NULL) + fatal(NULL); + $$->type = ACTION_SET_RELATIVE_MED; + $$->action.metric = $3; + } + | METRIC '-' number { + if ($3 > INT_MAX) { + yyerror("metric to small: min -%u", INT_MAX); + YYERROR; + } + if (($$ = calloc(1, sizeof(struct filter_set))) == NULL) + fatal(NULL); + $$->type = ACTION_SET_RELATIVE_MED; + $$->action.relative = -$3; + } | NEXTHOP address { if (($$ = calloc(1, sizeof(struct filter_set))) == NULL) fatal(NULL); diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c index f2901b3b287..ce32948047d 100644 --- a/usr.sbin/bgpd/printconf.c +++ b/usr.sbin/bgpd/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.36 2005/03/11 12:54:19 claudio Exp $ */ +/* $OpenBSD: printconf.c,v 1.37 2005/03/14 17:32:04 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -86,9 +86,15 @@ print_set(struct filter_set_head *set) case ACTION_SET_LOCALPREF: printf("localpref %u ", s->action.metric); break; + case ACTION_SET_RELATIVE_LOCALPREF: + printf("localpref %+d ", s->action.relative); + break; case ACTION_SET_MED: printf("metric %u ", s->action.metric); break; + case ACTION_SET_RELATIVE_MED: + printf("metric %+d ", s->action.relative); + break; case ACTION_SET_NEXTHOP: printf("nexthop %s ", log_addr(&s->action.nexthop)); break; diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c index 00f17db9798..65b48ff379d 100644 --- a/usr.sbin/bgpd/rde_filter.c +++ b/usr.sbin/bgpd/rde_filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_filter.c,v 1.25 2005/03/11 12:54:20 claudio Exp $ */ +/* $OpenBSD: rde_filter.c,v 1.26 2005/03/14 17:32:04 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> @@ -96,10 +96,41 @@ rde_apply_set(struct rde_aspath *asp, struct filter_set_head *sh, case ACTION_SET_LOCALPREF: asp->lpref = set->action.metric; break; + case ACTION_SET_RELATIVE_LOCALPREF: + if (set->action.relative > 0) { + if (set->action.relative + asp->lpref < + asp->lpref) + asp->lpref = UINT_MAX; + else + asp->lpref += set->action.relative; + } else { + if ((u_int32_t)-set->action.relative > + asp->lpref) + asp->lpref = 0; + else + asp->lpref += set->action.relative; + } + break; case ACTION_SET_MED: asp->flags |= F_ATTR_MED | F_ATTR_MED_ANNOUNCE; asp->med = set->action.metric; break; + case ACTION_SET_RELATIVE_MED: + asp->flags |= F_ATTR_MED | F_ATTR_MED_ANNOUNCE; + if (set->action.relative > 0) { + if (set->action.relative + asp->med < + asp->med) + asp->med = UINT_MAX; + else + asp->med += set->action.relative; + } else { + if ((u_int32_t)-set->action.relative > + asp->med) + asp->med = 0; + else + asp->med += set->action.relative; + } + break; case ACTION_SET_PREPEND_SELF: /* don't apply if this is a incoming default override */ if (dir == DIR_DEFAULT_IN) |