Re: Allow bgpd to filter on the nexthop attribute
On Sat, Nov 10, 2012 at 06:52:17PM +0100, Claudio Jeker wrote: > On Sat, Nov 10, 2012 at 03:38:15PM +0100, Claudio Jeker wrote: > > In some cases it helps to be able to restrict nexthops from pathes > > received. E.g. at IXP where only routes originating from the neighbor > > should be accepted. > > > > This diff implements this for bgpd. > > Updated diff that fixes a missing break. Found by Florian. Another bug found by Florian Obser. This time the "netxhop neighbor" feature crashed the rde because the asp passed around in the filter is not linked and therefor asp->peer is NULL. Oups. Since rde_filter() already carries the from peer just pass that info down. -- :wq Claudio Index: bgpd.conf.5 === RCS file: /cvs/src/usr.sbin/bgpd/bgpd.conf.5,v retrieving revision 1.121 diff -u -p -r1.121 bgpd.conf.5 --- bgpd.conf.5 24 Aug 2012 17:04:06 - 1.121 +++ bgpd.conf.5 28 Oct 2012 13:38:06 - @@ -1175,6 +1175,17 @@ is repeated more than .Ar len times. .Pp +.It Ic nexthop Ar address +This rule applies only to +.Em UPDATES +where the nexthop is equal to +.Ar address. +The +.Ar address +can be set to +.Em neighbor +in which case the nexthop is compared against the address of the neighbor. +.Pp .It Xo .Ic prefix .Ar address Ns Li / Ns Ar len Index: bgpd.h === RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v retrieving revision 1.273 diff -u -p -r1.273 bgpd.h --- bgpd.h 18 Sep 2012 10:10:00 - 1.273 +++ bgpd.h 28 Oct 2012 13:00:03 - @@ -749,6 +749,13 @@ struct filter_prefix { u_int8_tlen; }; +struct filter_nexthop { + struct bgpd_addraddr; + u_int8_tflags; +#define FILTER_NEXTHOP_ADDR1 +#define FILTER_NEXTHOP_NEIGHBOR2 +}; + struct filter_prefixlen { enum comp_ops op; u_int8_taid; @@ -759,6 +766,7 @@ struct filter_prefixlen { struct filter_match { struct filter_prefixprefix; struct filter_prefixlen prefixlen; + struct filter_nexthop nexthop; struct filter_asas; struct filter_aslen aslen; struct filter_community community; Index: parse.y === RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v retrieving revision 1.264 diff -u -p -r1.264 parse.y --- parse.y 23 Sep 2012 09:39:17 - 1.264 +++ parse.y 28 Oct 2012 13:29:16 - @@ -1700,6 +1700,26 @@ filter_elm : filter_prefix_h { } fmopts.aid = AID_INET6; } + | NEXTHOP address { + if (fmopts.m.nexthop.flags) { + yyerror("nexthop already specified"); + YYERROR; + } + if (fmopts.aid && fmopts.aid != $2.aid) { + yyerror("nexthop address family doesn't match " + "rule address family"); + YYERROR; + } + fmopts.m.nexthop.addr = $2; + fmopts.m.nexthop.flags = FILTER_NEXTHOP_ADDR; + } + | NEXTHOP NEIGHBOR { + if (fmopts.m.nexthop.flags) { + yyerror("nexthop already specified"); + YYERROR; + } + fmopts.m.nexthop.flags = FILTER_NEXTHOP_NEIGHBOR; + } ; prefixlenop: unaryop NUMBER{ Index: printconf.c === RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v retrieving revision 1.88 diff -u -p -r1.88 printconf.c --- printconf.c 23 Sep 2012 09:39:18 - 1.88 +++ printconf.c 28 Oct 2012 13:33:58 - @@ -561,6 +561,13 @@ print_rule(struct peer *peer_l, struct f } } + if (r->match.nexthop.flags) { + if (r->match.nexthop.flags == FILTER_NEXTHOP_NEIGHBOR) + printf("nexthop neighbor "); + else + printf("nexthop %s ", log_addr(&r->match.nexthop.addr)); + } + if (r->match.as.type) { if (r->match.as.type == AS_ALL) printf("AS %s ", log_as(r->match.as.as)); Index: rde_filter.c === RCS file: /cvs/src/usr.sbin/bgpd/rde_filter.c,v retrieving revision 1.67 diff -u -p -r1.67 rde_filter.c --- rde_filter.c20 Sep 2011 21:19:06 - 1.67 +++ rde_filter.c10 Nov 2012 20:56:14 - @@ -26,7 +26,7 @@ #include "rde.h" intrde_filter_match(struct filter_rule *
Re: Allow bgpd to filter on the nexthop attribute
On Sat, Nov 10, 2012 at 03:38:15PM +0100, Claudio Jeker wrote: > In some cases it helps to be able to restrict nexthops from pathes > received. E.g. at IXP where only routes originating from the neighbor > should be accepted. > > This diff implements this for bgpd. Updated diff that fixes a missing break. Found by Florian. -- :wq Claudio Index: bgpd.conf.5 === RCS file: /cvs/src/usr.sbin/bgpd/bgpd.conf.5,v retrieving revision 1.121 diff -u -p -r1.121 bgpd.conf.5 --- bgpd.conf.5 24 Aug 2012 17:04:06 - 1.121 +++ bgpd.conf.5 28 Oct 2012 13:38:06 - @@ -1175,6 +1175,17 @@ is repeated more than .Ar len times. .Pp +.It Ic nexthop Ar address +This rule applies only to +.Em UPDATES +where the nexthop is equal to +.Ar address. +The +.Ar address +can be set to +.Em neighbor +in which case the nexthop is compared against the address of the neighbor. +.Pp .It Xo .Ic prefix .Ar address Ns Li / Ns Ar len Index: bgpd.h === RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v retrieving revision 1.273 diff -u -p -r1.273 bgpd.h --- bgpd.h 18 Sep 2012 10:10:00 - 1.273 +++ bgpd.h 28 Oct 2012 13:00:03 - @@ -749,6 +749,13 @@ struct filter_prefix { u_int8_tlen; }; +struct filter_nexthop { + struct bgpd_addraddr; + u_int8_tflags; +#define FILTER_NEXTHOP_ADDR1 +#define FILTER_NEXTHOP_NEIGHBOR2 +}; + struct filter_prefixlen { enum comp_ops op; u_int8_taid; @@ -759,6 +766,7 @@ struct filter_prefixlen { struct filter_match { struct filter_prefixprefix; struct filter_prefixlen prefixlen; + struct filter_nexthop nexthop; struct filter_asas; struct filter_aslen aslen; struct filter_community community; Index: parse.y === RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v retrieving revision 1.264 diff -u -p -r1.264 parse.y --- parse.y 23 Sep 2012 09:39:17 - 1.264 +++ parse.y 28 Oct 2012 13:29:16 - @@ -1700,6 +1700,26 @@ filter_elm : filter_prefix_h { } fmopts.aid = AID_INET6; } + | NEXTHOP address { + if (fmopts.m.nexthop.flags) { + yyerror("nexthop already specified"); + YYERROR; + } + if (fmopts.aid && fmopts.aid != $2.aid) { + yyerror("nexthop address family doesn't match " + "rule address family"); + YYERROR; + } + fmopts.m.nexthop.addr = $2; + fmopts.m.nexthop.flags = FILTER_NEXTHOP_ADDR; + } + | NEXTHOP NEIGHBOR { + if (fmopts.m.nexthop.flags) { + yyerror("nexthop already specified"); + YYERROR; + } + fmopts.m.nexthop.flags = FILTER_NEXTHOP_NEIGHBOR; + } ; prefixlenop: unaryop NUMBER{ Index: printconf.c === RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v retrieving revision 1.88 diff -u -p -r1.88 printconf.c --- printconf.c 23 Sep 2012 09:39:18 - 1.88 +++ printconf.c 28 Oct 2012 13:33:58 - @@ -561,6 +561,13 @@ print_rule(struct peer *peer_l, struct f } } + if (r->match.nexthop.flags) { + if (r->match.nexthop.flags == FILTER_NEXTHOP_NEIGHBOR) + printf("nexthop neighbor "); + else + printf("nexthop %s ", log_addr(&r->match.nexthop.addr)); + } + if (r->match.as.type) { if (r->match.as.type == AS_ALL) printf("AS %s ", log_as(r->match.as.as)); Index: rde_filter.c === RCS file: /cvs/src/usr.sbin/bgpd/rde_filter.c,v retrieving revision 1.67 diff -u -p -r1.67 rde_filter.c --- rde_filter.c20 Sep 2011 21:19:06 - 1.67 +++ rde_filter.c10 Nov 2012 17:50:31 - @@ -384,6 +384,34 @@ rde_filter_match(struct filter_rule *f, } /* NOTREACHED */ } + if (f->match.nexthop.flags != 0) { + struct bgpd_addr *nexthop, *cmpaddr; + if (asp->nexthop == NULL) + /* no nexthop, skip */ + return (0); + nexthop = &asp->nexthop->exit_nexthop; + if (f->match
Allow bgpd to filter on the nexthop attribute
In some cases it helps to be able to restrict nexthops from pathes received. E.g. at IXP where only routes originating from the neighbor should be accepted. This diff implements this for bgpd. OK? -- :wq Claudio Index: bgpd.conf.5 === RCS file: /cvs/src/usr.sbin/bgpd/bgpd.conf.5,v retrieving revision 1.121 diff -u -p -r1.121 bgpd.conf.5 --- bgpd.conf.5 24 Aug 2012 17:04:06 - 1.121 +++ bgpd.conf.5 28 Oct 2012 13:38:06 - @@ -1175,6 +1175,17 @@ is repeated more than .Ar len times. .Pp +.It Ic nexthop Ar address +This rule applies only to +.Em UPDATES +where the nexthop is equal to +.Ar address. +The +.Ar address +can be set to +.Em neighbor +in which case the nexthop is compared against the address of the neighbor. +.Pp .It Xo .Ic prefix .Ar address Ns Li / Ns Ar len Index: bgpd.h === RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v retrieving revision 1.273 diff -u -p -r1.273 bgpd.h --- bgpd.h 18 Sep 2012 10:10:00 - 1.273 +++ bgpd.h 28 Oct 2012 13:00:03 - @@ -749,6 +749,13 @@ struct filter_prefix { u_int8_tlen; }; +struct filter_nexthop { + struct bgpd_addraddr; + u_int8_tflags; +#define FILTER_NEXTHOP_ADDR1 +#define FILTER_NEXTHOP_NEIGHBOR2 +}; + struct filter_prefixlen { enum comp_ops op; u_int8_taid; @@ -759,6 +766,7 @@ struct filter_prefixlen { struct filter_match { struct filter_prefixprefix; struct filter_prefixlen prefixlen; + struct filter_nexthop nexthop; struct filter_asas; struct filter_aslen aslen; struct filter_community community; Index: parse.y === RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v retrieving revision 1.264 diff -u -p -r1.264 parse.y --- parse.y 23 Sep 2012 09:39:17 - 1.264 +++ parse.y 28 Oct 2012 13:29:16 - @@ -1700,6 +1700,26 @@ filter_elm : filter_prefix_h { } fmopts.aid = AID_INET6; } + | NEXTHOP address { + if (fmopts.m.nexthop.flags) { + yyerror("nexthop already specified"); + YYERROR; + } + if (fmopts.aid && fmopts.aid != $2.aid) { + yyerror("nexthop address family doesn't match " + "rule address family"); + YYERROR; + } + fmopts.m.nexthop.addr = $2; + fmopts.m.nexthop.flags = FILTER_NEXTHOP_ADDR; + } + | NEXTHOP NEIGHBOR { + if (fmopts.m.nexthop.flags) { + yyerror("nexthop already specified"); + YYERROR; + } + fmopts.m.nexthop.flags = FILTER_NEXTHOP_NEIGHBOR; + } ; prefixlenop: unaryop NUMBER{ Index: printconf.c === RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v retrieving revision 1.88 diff -u -p -r1.88 printconf.c --- printconf.c 23 Sep 2012 09:39:18 - 1.88 +++ printconf.c 28 Oct 2012 13:33:58 - @@ -561,6 +561,13 @@ print_rule(struct peer *peer_l, struct f } } + if (r->match.nexthop.flags) { + if (r->match.nexthop.flags == FILTER_NEXTHOP_NEIGHBOR) + printf("nexthop neighbor "); + else + printf("nexthop %s ", log_addr(&r->match.nexthop.addr)); + } + if (r->match.as.type) { if (r->match.as.type == AS_ALL) printf("AS %s ", log_as(r->match.as.as)); Index: rde_filter.c === RCS file: /cvs/src/usr.sbin/bgpd/rde_filter.c,v retrieving revision 1.67 diff -u -p -r1.67 rde_filter.c --- rde_filter.c20 Sep 2011 21:19:06 - 1.67 +++ rde_filter.c29 Oct 2012 06:55:06 - @@ -384,6 +384,33 @@ rde_filter_match(struct filter_rule *f, } /* NOTREACHED */ } + if (f->match.nexthop.flags != 0) { + struct bgpd_addr *nexthop, *cmpaddr; + if (asp->nexthop == NULL) + /* no nexthop, skip */ + return (0); + nexthop = &asp->nexthop->exit_nexthop; + if (f->match.nexthop.flags == FILTER_NEXTHOP_ADDR) + cmpaddr = &f->match.nexthop.addr; + else +