-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
1 parent
52483fa
commit e5c83d9
Showing
35 changed files
with
3,861 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
!Makefile | ||
Makefile.in | ||
libpbr.a | ||
pbrd | ||
tags | ||
TAGS | ||
.deps | ||
*.o | ||
*.lo | ||
*.la | ||
*.libs | ||
.arch-inventory | ||
.arch-ids | ||
*~ | ||
*.loT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
all: ALWAYS | ||
@$(MAKE) -s -C .. pbrd/pbrd | ||
%: ALWAYS | ||
@$(MAKE) -s -C .. pbrd/$@ | ||
|
||
Makefile: | ||
#nothing | ||
ALWAYS: | ||
.PHONY: ALWAYS makefiles | ||
.SUFFIXES: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
/* | ||
* PBR - debugging | ||
* Copyright (C) 2018 Cumulus Networks, Inc. | ||
* Quentin Young | ||
* | ||
* This program 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 of the License, or (at your option) | ||
* any later version. | ||
* | ||
* This program 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 | ||
*/ | ||
#include <zebra.h> | ||
|
||
#include "debug.h" | ||
#include "command.h" | ||
#include "vector.h" | ||
|
||
#ifndef VTYSH_EXTRACT_PL | ||
#include "pbrd/pbr_debug_clippy.c" | ||
#endif | ||
#include "pbrd/pbr_debug.h" | ||
|
||
struct debug pbr_dbg_map = {0, "PBR map"}; | ||
struct debug pbr_dbg_zebra = {0, "PBR Zebra communications"}; | ||
struct debug pbr_dbg_nht = {0, "PBR nexthop tracking"}; | ||
struct debug pbr_dbg_event = {0, "PBR events"}; | ||
|
||
struct debug *pbr_debugs[] = {&pbr_dbg_map, &pbr_dbg_zebra, &pbr_dbg_nht, | ||
&pbr_dbg_event}; | ||
|
||
const char *pbr_debugs_conflines[] = { | ||
"debug pbr map", | ||
"debug pbr zebra", | ||
"debug pbr nht", | ||
"debug pbr events", | ||
}; | ||
|
||
/* | ||
* Set or unset flags on all debugs for pbrd. | ||
* | ||
* flags | ||
* The flags to set | ||
* | ||
* set | ||
* Whether to set or unset the specified flags | ||
*/ | ||
static void pbr_debug_set_all(uint32_t flags, bool set) | ||
{ | ||
for (unsigned int i = 0; i < array_size(pbr_debugs); i++) { | ||
DEBUG_FLAGS_SET(pbr_debugs[i], flags, set); | ||
|
||
/* if all modes have been turned off, don't preserve options */ | ||
if (!DEBUG_MODE_CHECK(pbr_debugs[i], DEBUG_MODE_ALL)) | ||
DEBUG_CLEAR(pbr_debugs[i]); | ||
} | ||
} | ||
|
||
/* | ||
* Check flags on all debugs for pbrd. | ||
* | ||
* flags | ||
* The flags to set | ||
* | ||
* Returns: | ||
* The subset of the given flags that were set in all pbrd debugs | ||
*/ | ||
static uint32_t pbr_debug_check_all(uint32_t flags) | ||
{ | ||
uint32_t mode = DEBUG_MODE_ALL; | ||
for (unsigned int i = 0; i < array_size(pbr_debugs); i++) | ||
mode &= DEBUG_MODE_CHECK(pbr_debugs[i], flags); | ||
return mode; | ||
} | ||
|
||
static int pbr_debug_config_write_helper(struct vty *vty, bool config) | ||
{ | ||
uint32_t mode = DEBUG_MODE_ALL; | ||
|
||
if (config) | ||
mode = DEBUG_MODE_CONF; | ||
|
||
if (pbr_debug_check_all(DEBUG_MODE_CONF) == mode) { | ||
vty_out(vty, "debug pbr\n"); | ||
return 0; | ||
} | ||
|
||
for (unsigned int i = 0; i < array_size(pbr_debugs); i++) | ||
if (DEBUG_MODE_CHECK(pbr_debugs[i], mode)) | ||
vty_out(vty, "%s\n", pbr_debugs_conflines[i]); | ||
return 0; | ||
} | ||
|
||
int pbr_debug_config_write(struct vty *vty) | ||
{ | ||
return pbr_debug_config_write_helper(vty, true); | ||
} | ||
|
||
/* PBR debugging CLI ------------------------------------------------------- */ | ||
/* clang-format off */ | ||
|
||
DEFPY(debug_pbr, | ||
debug_pbr_cmd, | ||
"[no] debug pbr [{map$map|zebra$zebra|nht$nht|events$events}]", | ||
NO_STR | ||
DEBUG_STR | ||
"Policy Based Routing\n" | ||
"Policy maps\n" | ||
"PBRD <-> Zebra communications\n" | ||
"Nexthop tracking\n" | ||
"Events\n") | ||
{ | ||
uint32_t mode = DEBUG_NODE2MODE(vty->node); | ||
if (map) | ||
DEBUG_MODE_SET(&pbr_dbg_map, mode, !no); | ||
if (zebra) | ||
DEBUG_MODE_SET(&pbr_dbg_zebra, mode, !no); | ||
if (nht) | ||
DEBUG_MODE_SET(&pbr_dbg_nht, mode, !no); | ||
if (events) | ||
DEBUG_MODE_SET(&pbr_dbg_event, mode, !no); | ||
|
||
/* no specific debug --> act on all of them */ | ||
if (strmatch(argv[argc - 1]->text, "pbr")) | ||
pbr_debug_set_all(mode, !no); | ||
|
||
return CMD_SUCCESS; | ||
} | ||
|
||
DEFUN_NOSH(show_debugging_pbr, | ||
show_debugging_pbr_cmd, | ||
"show debugging [pbr]", | ||
SHOW_STR | ||
DEBUG_STR | ||
"Policy Based Routing\n") | ||
{ | ||
vty_out(vty, "PBR debugging status:\n"); | ||
|
||
pbr_debug_config_write_helper(vty, false); | ||
|
||
return CMD_SUCCESS; | ||
} | ||
|
||
/* clang-format on */ | ||
/* ------------------------------------------------------------------------- */ | ||
|
||
static struct cmd_node debug_node = {DEBUG_NODE, "", 1}; | ||
|
||
struct debug_callbacks pbr_dbg_cbs = {.debug_set_all = pbr_debug_set_all}; | ||
|
||
void pbr_debug_init(void) | ||
{ | ||
debug_init(&pbr_dbg_cbs); | ||
} | ||
|
||
void pbr_debug_init_vty(void) | ||
{ | ||
install_node(&debug_node, pbr_debug_config_write); | ||
|
||
install_element(VIEW_NODE, &debug_pbr_cmd); | ||
install_element(CONFIG_NODE, &debug_pbr_cmd); | ||
|
||
install_element(VIEW_NODE, &show_debugging_pbr_cmd); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* | ||
* PBR - debugging | ||
* Copyright (C) 2018 Cumulus Networks, Inc. | ||
* Quentin Young | ||
* | ||
* This program 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 of the License, or (at your option) | ||
* any later version. | ||
* | ||
* This program 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_DEBUG_H__ | ||
#define __PBR_DEBUG_H__ | ||
|
||
#include <zebra.h> | ||
|
||
#include "debug.h" | ||
|
||
/* PBR debugging records */ | ||
extern struct debug pbr_dbg_map; | ||
extern struct debug pbr_dbg_zebra; | ||
extern struct debug pbr_dbg_nht; | ||
extern struct debug pbr_dbg_event; | ||
|
||
/* | ||
* Initialize PBR debugging. | ||
* | ||
* Installs VTY commands and registers callbacks. | ||
*/ | ||
void pbr_debug_init(void); | ||
|
||
/* | ||
* Install PBR debugging VTY commands. | ||
*/ | ||
void pbr_debug_init_vty(void); | ||
|
||
/* | ||
* Print PBR debugging configuration. | ||
* | ||
* vty | ||
* VTY to print debugging configuration to. | ||
*/ | ||
int pbr_debug_config_write(struct vty *vty); | ||
|
||
#endif /* __PBR_DEBUG_H__ */ |
Oops, something went wrong.