diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-01-23 19:11:36 +0100 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-04-06 19:22:43 +0200 |
commit | e5c83d9b314cb513e78707de5d29ec655dbdca7e (patch) | |
tree | 0ede3af459164c589f9892e7f6c93e82f08ad208 /pbrd/pbr_nht.h | |
parent | Merge pull request #2029 from cdwertmann/patch-1 (diff) | |
download | frr-e5c83d9b314cb513e78707de5d29ec655dbdca7e.tar.xz frr-e5c83d9b314cb513e78707de5d29ec655dbdca7e.zip |
pbrd: Add PBR to FRR
This is an implementation of PBR for FRR.
This implemenation uses a combination of rules and
tables to determine how packets will flow.
PBR introduces a new concept of 'nexthop-groups' to
specify a group of nexthops that will be used for
ecmp. Nexthop-groups are specified on the cli via:
nexthop-group DONNA
nexthop 192.168.208.1
nexthop 192.168.209.1
nexthop 192.168.210.1
!
PBR sees the nexthop-group and installs these as a default
route with these nexthops starting at table 10000
robot# show pbr nexthop-groups
Nexthop-Group: DONNA Table: 10001 Valid: 1 Installed: 1
Valid: 1 nexthop 192.168.209.1
Valid: 1 nexthop 192.168.210.1
Valid: 1 nexthop 192.168.208.1
I have also introduced the ability to specify a table
in a 'show ip route table XXX' to see the specified tables.
robot# show ip route table 10001
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, P - PIM, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR,
> - selected route, * - FIB route
F>* 0.0.0.0/0 [0/0] via 192.168.208.1, enp0s8, 00:14:25
* via 192.168.209.1, enp0s9, 00:14:25
* via 192.168.210.1, enp0s10, 00:14:25
PBR tracks PBR-MAPS via the pbr-map command:
!
pbr-map EVA seq 10
match src-ip 4.3.4.0/24
set nexthop-group DONNA
!
pbr-map EVA seq 20
match dst-ip 4.3.5.0/24
set nexthop-group DONNA
!
pbr-maps can have 'match src-ip <prefix>' and 'match dst-ip <prefix>'
to affect decisions about incoming packets. Additionally if you
only have one nexthop to use for a pbr-map you do not need
to setup a nexthop-group and can specify 'set nexthop XXXX'.
To apply the pbr-map to an incoming interface you do this:
interface enp0s10
pbr-policy EVA
!
When a pbr-map is applied to interfaces it can be installed
into the kernel as a rule:
[sharpd@robot frr1]$ ip rule show
0: from all lookup local
309: from 4.3.4.0/24 iif enp0s10 lookup 10001
319: from all to 4.3.5.0/24 iif enp0s10 lookup 10001
1000: from all lookup [l3mdev-table]
32766: from all lookup main
32767: from all lookup default
[sharpd@robot frr1]$ ip route show table 10001
default proto pbr metric 20
nexthop via 192.168.208.1 dev enp0s8 weight 1
nexthop via 192.168.209.1 dev enp0s9 weight 1
nexthop via 192.168.210.1 dev enp0s10 weight 1
The linux kernel now will use the rules and tables to properly
apply these policies.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'pbrd/pbr_nht.h')
-rw-r--r-- | pbrd/pbr_nht.h | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/pbrd/pbr_nht.h b/pbrd/pbr_nht.h new file mode 100644 index 000000000..2508f49e4 --- /dev/null +++ b/pbrd/pbr_nht.h @@ -0,0 +1,113 @@ +/* + * PBR-nht Header + * Copyright (C) 2018 Cumulus Networks, Inc. + * Donald Sharp + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __PBR_NHT_H__ +#define __PBR_NHT_H__ + +#include <lib/zclient.h> +#include <lib/nexthop_group.h> + +struct pbr_nexthop_group_cache { + char name[PBR_MAP_NAMELEN]; + + uint32_t table_id; + + struct hash *nhh; + + /* + * If all nexthops are considered valid + */ + bool valid; + + bool installed; +}; + +struct pbr_nexthop_cache { + struct pbr_nexthop_group_cache *parent; + + struct nexthop nexthop; + + bool valid; +}; + +extern void pbr_nht_write_table_range(struct vty *vty); +#define PBR_NHT_DEFAULT_LOW_TABLEID 10000 +#define PBR_NHT_DEFAULT_HIGH_TABLEID 11000 +extern void pbr_nht_set_tableid_range(uint32_t low, uint32_t high); + +/* + * Get the next tableid to use for installation + */ +extern uint32_t pbr_nht_get_next_tableid(void); +/* + * Get the next rule number to use for installation + */ +extern void pbr_nht_write_rule_range(struct vty *vty); + +#define PBR_NHT_DEFAULT_LOW_RULE 300 +#define PBR_NHT_DEFAULT_HIGH_RULE 1300 +extern void pbr_nht_set_rule_range(uint32_t low, uint32_t high); + +extern uint32_t pbr_nht_get_next_rule(uint32_t seqno); + +extern void pbr_nhgroup_add_cb(const char *name); +extern void pbr_nhgroup_add_nexthop_cb(const struct nexthop_group_cmd *nhg, + const struct nexthop *nhop); +extern void pbr_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhg, + const struct nexthop *nhop); +extern void pbr_nhgroup_delete_cb(const char *name); + +extern bool pbr_nht_nexthop_valid(struct nexthop_group *nhg); +extern bool pbr_nht_nexthop_group_valid(const char *name); + +extern void pbr_nht_add_group(const char *name); +extern void pbr_nht_change_group(const char *name); +extern void pbr_nht_delete_group(const char *name); + +extern void pbr_nht_add_individual_nexthop(const char *name, uint32_t seqno); +extern void pbr_nht_delete_individual_nexthop(const char *name, uint32_t seqno); +/* + * Given the tableid of the installed default + * route, find the nexthop-group associated with + * it, then find all pbr-maps that use it and + * install/delete them as well. + */ +extern void pbr_nht_route_installed_for_table(uint32_t table_id); +extern void pbr_nht_route_removed_for_table(uint32_t table_id); + +/* + * Given the nexthop group name, lookup the associated + * tableid with it + */ +extern uint32_t pbr_nht_get_table(const char *name); + +extern bool pbr_nht_get_installed(const char *name); + +extern char *pbr_nht_nexthop_make_name(char *name, size_t l, uint32_t seqno, + char *buffer); + +extern void pbr_nht_show_nexthop_group(struct vty *vty, const char *name); + +/* + * When we get a callback from zebra about a nexthop changing + */ +extern void pbr_nht_nexthop_update(struct zapi_route *nhr); + +extern void pbr_nht_init(void); +#endif |