Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pbrd: nexthop refcounting #24

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ include babeld/subdir.am
include eigrpd/subdir.am
include sharpd/subdir.am
include pimd/subdir.am
include pbrd/subdir.am

SUBDIRS = . @LIBRFP@ @RFPTEST@ \
@BGPD@ \
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,7 @@ AM_CONDITIONAL(BABELD, test "${enable_babeld}" != "no")
AM_CONDITIONAL(OSPF6D, test "${enable_ospf6d}" != "no")
AM_CONDITIONAL(ISISD, test "${enable_isisd}" != "no")
AM_CONDITIONAL(PIMD, test "${enable_pimd}" != "no")
AM_CONDITIONAL(PBRD, test "${enable_pbrd}" != "no")

if test "${enable_bgp_announce}" = "no";then
AC_DEFINE(DISABLE_BGP_ANNOUNCE,1,Disable BGP installation to zebra)
Expand Down
1 change: 1 addition & 0 deletions doc/manpages/common-options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ These following options control the daemon's VTY (interactive command line) inte
pimd 2611
ldpd 2612
eigrpd 2613
pbrd 2615

Port 2607 is used for ospfd's Opaque LSA API, while port 2600 is used for the (insecure) TCP-ZEBRA interface.

Expand Down
1 change: 1 addition & 0 deletions doc/manpages/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@
('ldpd', 'ldpd', fwfrr.format("an LDP "), [], 8),
('nhrpd', 'nhrpd', fwfrr.format("a Next Hop Routing Protocol "), [], 8),
('pimd', 'pimd', fwfrr.format("a PIM "), [], 8),
('pbrd', 'pbrd', fwfrr.format("a PBR "), [], 8),
('mtracebis', 'mtracebis', "a multicast trace client", [], 8),
('ripd', 'ripd', fwfrr.format("a RIP "), [], 8),
('ripngd', 'ripngd', fwfrr.format("a RIPNG "), [], 8),
Expand Down
2 changes: 1 addition & 1 deletion doc/manpages/defines.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
.. |synopsis-options| replace:: [-d|-t|-dt] [-C] [-f config-file] [-i pid-file] [-z zclient-path] [-u user] [-g group] [-A vty-addr] [-P vty-port] [-M module[:options]] [-N pathspace] [--vty_socket vty-path] [--moduledir module-path]
.. |synopsis-options-hv| replace:: [-h] [-v]
.. |seealso-programs| replace:: zebra(8), vtysh(1), ripd(8), ripngd(8), ospfd(8), ospf6d(8), bgpd(8), isisd(8), babeld(8), nhrpd(8), pimd(8), ldpd(8), eigrpd(8), mtracebis(8)
.. |seealso-programs| replace:: zebra(8), vtysh(1), ripd(8), ripngd(8), ospfd(8), ospf6d(8), bgpd(8), isisd(8), babeld(8), nhrpd(8), pimd(8), pbrd(8), ldpd(8), eigrpd(8), mtracebis(8)
1 change: 1 addition & 0 deletions doc/manpages/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Welcome to FRR's documentation!
ospfclient
ospfd
pimd
pbrd
mtracebis
ripd
ripngd
Expand Down
39 changes: 39 additions & 0 deletions doc/manpages/pbrd.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
****
PBRD
****

.. include:: defines.rst
.. |DAEMON| replace:: pbrd

SYNOPSIS
========
|DAEMON| |synopsis-options-hv|

|DAEMON| |synopsis-options|

DESCRIPTION
===========
|DAEMON| is a routing component that works with the FRRouting engine.

OPTIONS
=======
OPTIONS available for the |DAEMON| command:

.. include:: common-options.rst

FILES
=====

|INSTALL_PREFIX_SBIN|/|DAEMON|
The default location of the |DAEMON| binary.

|INSTALL_PREFIX_ETC|/|DAEMON|.conf
The default location of the |DAEMON| config file.

$(PWD)/|DAEMON|.log
If the |DAEMON| process is configured to output logs to a file, then you
will find this file in the directory where you started |DAEMON|.

.. include:: epilogue.rst


1 change: 1 addition & 0 deletions doc/user/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Welcome to FRR's documentation!
ospfd
ospf6d
pim
pbr
ripd
ripngd
vnc
Expand Down
130 changes: 130 additions & 0 deletions doc/user/pbr.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
.. _pbr:

***
PBR
***

:abbr:`PBR` is Policy Based Routing. This implementation supports a very
simple interface to allow admins to influence routing on their router. At
this time you can only match on destination and source prefixes for
an incoming interface. At this point in time, this implementation will
only work on Linux.

.. _starting-pbr:

STARTING PBR
============

Default configuration file for *pbrd* is :file:`pbrd.conf`. The typical
location of :file:`pbrd.conf` is |INSTALL_PREFIX_ETC|/pbrd.conf.

If the user is using integrated config, then :file:`pbrd.conf` need
not be present and the :file:`frr.conf` is read instead.

.. program:: pbrd

:abbr:`PBR` supports all the common FRR daemon start options which are
documented elsewhere.

.. _nexthop-groups:

NEXTHOP GROUPS
==============

Nexthop groups are a way to encapsulate ECMP information together. It's a
listing of ECMP nexthops used to forward packets for when a pbr-map is
matched.

.. index:: nexthop-group
.. clicmd:: nexthop-group NAME

Create a nexthop-group with an associated NAME. This will put
you into a sub-mode where you can specify individual nexthops.
To exit this mode type exit or end as per normal conventions
for leaving a sub-mode.

.. clicmd:: nexthop [A.B.C.D|X:X::X:XX] [interface] [nexthop-vrf NAME]

Create a v4 or v6 nexthop. All normal rules for creating nexthops
that you are used to are allowed here. The syntax was intentionally
kept the same as creating nexthops as you would for static routes.

.. _pbr-maps:

PBR MAPS
========

PBR MAPS are a way to group policies that we would like to apply
to individual interfaces. These policies when applied are matched
against incoming packets. If matched the nexthop-group or nexthop
is used to forward the packets to the end destination

.. index:: pbr-map
.. clicmd:: pbr-map NAME seq (1-1000)

Create a pbr-map with NAME and sequence number specified. This
command puts you into a new submode for pbr-map specification.
To exit this mode type exit or end as per normal conventions
for leaving a sub-mode.

.. index:: match
.. clicmd:: match src-ip <PREFIX>

When a incoming packet matches the source prefix specified, take the packet
and forward according to the nexthops specified. This command
accepts both v4 and v6 prefixes. This command is used in
conjunction of the 'match dst-ip <PREFIX>' command for matching.

.. clicmd:: match dst-ip <PREFIX>

When a incoming packet matches the destination prefix specified, take
the packet and forward according to the nexthops specified. This
command accepts both v4 and v6 prefixes. This command is used in
conjuction of the 'match src-ip <PREFIX>' command for matching.

.. clicmd:: set nexthop-group NAME

Use the nexthop-group NAME as the place to forward packets when
the match commands have matched a packet.

.. clicmd:: set nexthop [A.B.C.D|X:X::X:XX] [interface] [nexthop-vrf NAME]

Use this individual nexthop as the place to forward packets when
the match commands have matched a packet.

.. _pbr-policy:

PBR POLICY
==========

After you have specified a PBR MAP, in order for it to be turned on,
you must apply the PBR MAP to an interface. This policy application
to an interface causes the policy to be installed into the kernel.

..index:: pbr-policy
.. clicmd:: pbr-policy NAME

This command is available under interface sub-mode. This turns
on the PBR MAP NAME and allows it to work properly.

.. _pbr-details:

PBR DETAILS
===========

Under the covers a PBR MAP is translated into two separate constructs
in the linux kernel.

..index:: Rules

The PBR MAP specified creates a `ip rule ...` that is inserted into
the linux kernel that points to a table to use for forwarding once
the rule matches.

..index:: Tables

The creation of a nexthop or nexthop-group is translated to a default
route in a table with the nexthops specified as the nexthops for the
default route.


3 changes: 3 additions & 0 deletions lib/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ const char *node_names[] = {
"as list", // AS_LIST_NODE,
"community list", // COMMUNITY_LIST_NODE,
"routemap", // RMAP_NODE,
"pbr-map", // PBRMAP_NODE,
"smux", // SMUX_NODE,
"dump", // DUMP_NODE,
"forwarding", // FORWARDING_NODE,
Expand Down Expand Up @@ -1314,6 +1315,7 @@ void cmd_exit(struct vty *vty)
case KEYCHAIN_NODE:
case MASC_NODE:
case RMAP_NODE:
case PBRMAP_NODE:
case VTY_NODE:
vty->node = CONFIG_NODE;
break;
Expand Down Expand Up @@ -1411,6 +1413,7 @@ DEFUN (config_end,
case BGP_EVPN_VNI_NODE:
case BGP_IPV6L_NODE:
case RMAP_NODE:
case PBRMAP_NODE:
case OSPF_NODE:
case OSPF6_NODE:
case LDP_NODE:
Expand Down
1 change: 1 addition & 0 deletions lib/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ enum node_type {
AS_LIST_NODE, /* AS list node. */
COMMUNITY_LIST_NODE, /* Community list node. */
RMAP_NODE, /* Route map node. */
PBRMAP_NODE, /* PBR map node. */
SMUX_NODE, /* SNMP configuration node. */
DUMP_NODE, /* Packet dump node. */
FORWARDING_NODE, /* IP forwarding node. */
Expand Down
13 changes: 13 additions & 0 deletions lib/nexthop.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "prefix.h"
#include "nexthop.h"
#include "mpls.h"
#include "jhash.h"

DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop")
DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label")
Expand Down Expand Up @@ -310,3 +311,15 @@ unsigned int nexthop_level(struct nexthop *nexthop)

return rv;
}

uint32_t nexthop_hash(struct nexthop *nexthop)
{
uint32_t key;

key = jhash_1word(nexthop->vrf_id, 0x45afe398);
key = jhash_1word(nexthop->ifindex, key);
key = jhash_1word(nexthop->type, key);
key = jhash(&nexthop->gate, sizeof(union g_addr), key);

return key;
}
17 changes: 17 additions & 0 deletions lib/nexthop.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,23 @@ void nexthop_add_labels(struct nexthop *, enum lsp_types_t, u_int8_t,
mpls_label_t *);
void nexthop_del_labels(struct nexthop *);

/*
* Hash a nexthop. Suitable for use with hash tables.
*
* This function uses the following values when computing the hash:
* - vrf_id
* - ifindex
* - type
* - gate
*
* nexthop
* The nexthop to hash
*
* Returns:
* 32-bit hash of nexthop
*/
uint32_t nexthop_hash(struct nexthop *nexthop);

extern bool nexthop_same(const struct nexthop *nh1, const struct nexthop *nh2);

extern const char *nexthop_type_to_str(enum nexthop_types_t nh_type);
Expand Down
2 changes: 2 additions & 0 deletions lib/route_types.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ ZEBRA_ROUTE_BGP_DIRECT_EXT, bgp-direct-to-nve-groups, NULL, 'e', 0, 0, "BGP2VNC"
ZEBRA_ROUTE_BGP_VPN, vpn, NULL, 'c', 1, 1, "VPN", bgpd
ZEBRA_ROUTE_BABEL, babel, babeld, 'A', 1, 1, "Babel"
ZEBRA_ROUTE_SHARP, sharp, sharpd, 'D', 1, 1, "SHARP"
ZEBRA_ROUTE_PBR, pbr, pbrd, 'F', 1, 1, "PBR"
ZEBRA_ROUTE_ALL, wildcard, none, '-', 0, 0, "-"


Expand All @@ -105,3 +106,4 @@ ZEBRA_ROUTE_VNC_DIRECT, "VNC direct (not via zebra) routes"
ZEBRA_ROUTE_BGP_VPN, "BGP VPN routes"
ZEBRA_ROUTE_BABEL, "Babel routing protocol (Babel)"
ZEBRA_ROUTE_SHARP, "Super Happy Advanced Routing Protocol (sharpd)"
ZEBRA_ROUTE_PBR, "Policy Based Routing (PBR)"
2 changes: 2 additions & 0 deletions lib/vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,7 @@ static void vty_end_config(struct vty *vty)
case BGP_EVPN_NODE:
case BGP_IPV6L_NODE:
case RMAP_NODE:
case PBRMAP_NODE:
case OSPF_NODE:
case OSPF6_NODE:
case LDP_NODE:
Expand Down Expand Up @@ -1116,6 +1117,7 @@ static void vty_stop_input(struct vty *vty)
case EIGRP_NODE:
case BGP_NODE:
case RMAP_NODE:
case PBRMAP_NODE:
case OSPF_NODE:
case OSPF6_NODE:
case LDP_NODE:
Expand Down
16 changes: 16 additions & 0 deletions pbrd/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
!Makefile
Makefile.in
libpbr.a
pbrd
tags
TAGS
.deps
*.o
*.lo
*.la
*.libs
.arch-inventory
.arch-ids
*clippy.c
*~
*.loT
10 changes: 10 additions & 0 deletions pbrd/Makefile
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:
Loading