diff options
| author | Stephen Worley <sworley@cumulusnetworks.com> | 2019-09-27 16:38:31 -0400 |
|---|---|---|
| committer | Stephen Worley <sworley@cumulusnetworks.com> | 2019-11-21 16:59:42 -0500 |
| commit | be3b67b5ef82d2f1f9f0f63190dd65c2bc47ebbf (patch) | |
| tree | 47fdc3253148c9b0e9f31ebf8e71afcc7993e99f /pbrd/pbr_vrf.c | |
| parent | 2d7ef3bba7eeb00adf2aceeca4747b59f4ac5fc7 (diff) | |
pbrd: Add `set vrf NAME` and `set vrf unchanged`
`set vrf NAME` allows the pbr map to point to an arbitrary vrf table.
`set vrf unchanged` will use the interface's vrf for table lookup.
Further, add functionality for pbr to respond to interface events
such as interface vrf changes & interface creation/deletion.
Ex)
ubuntu_nh# show pbr map
pbr-map TEST valid: 1
Seq: 1 rule: 300 Installed: 3(1) Reason: Valid
SRC Match: 3.3.3.3/32
VRF Unchanged (use interface vrf)
pbr-map TEST2 valid: 1
Seq: 2 rule: 301 Installed: 3(2) Reason: Valid
SRC Match: 4.4.4.4/32
VRF Lookup: vrf-red
root@ubuntu_nh:/home# ip rule show
0: from all lookup local
300: from 3.3.3.3 iif dummy2 lookup main
300: from 3.3.3.3 iif dummyVRF lookup 1111
301: from 4.4.4.4 iif dummy1 lookup 1111
301: from 4.4.4.4 iif dummy3 lookup 1111
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com-
Diffstat (limited to 'pbrd/pbr_vrf.c')
| -rw-r--r-- | pbrd/pbr_vrf.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/pbrd/pbr_vrf.c b/pbrd/pbr_vrf.c new file mode 100644 index 0000000000..d5a2bd0fef --- /dev/null +++ b/pbrd/pbr_vrf.c @@ -0,0 +1,137 @@ +/* + * PBR - vrf code + * Copyright (C) 2019 Cumulus Networks, Inc. + * Stephen Worley + * + * 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 + */ +#include <zebra.h> + +#include "vrf.h" + +#include "pbr_vrf.h" +#include "pbr_memory.h" +#include "pbr_map.h" +#include "pbr_debug.h" + +DEFINE_MTYPE_STATIC(PBRD, PBR_MAP_VRF, "PBR Map VRF") + +static struct pbr_vrf *pbr_vrf_alloc(void) +{ + struct pbr_vrf *pbr_vrf; + + pbr_vrf = XCALLOC(MTYPE_PBR_MAP_VRF, sizeof(struct pbr_vrf)); + + return pbr_vrf; +} + +static void pbr_vrf_free(struct pbr_vrf *pbr_vrf) +{ + XFREE(MTYPE_PBR_MAP_VRF, pbr_vrf); +} + +static int pbr_vrf_new(struct vrf *vrf) +{ + struct pbr_vrf *pbr_vrf; + + DEBUGD(&pbr_dbg_event, "%s: %u (%s)", __func__, vrf->vrf_id, vrf->name); + + pbr_vrf = pbr_vrf_alloc(); + vrf->info = pbr_vrf; + pbr_vrf->vrf = vrf; + + return 0; +} + +static int pbr_vrf_enable(struct vrf *vrf) +{ + DEBUGD(&pbr_dbg_event, "%s: %u (%s)", __func__, vrf->vrf_id, vrf->name); + + pbr_map_vrf_update(vrf->info); + + return 0; +} + +static int pbr_vrf_disable(struct vrf *vrf) +{ + DEBUGD(&pbr_dbg_event, "%s: %u (%s)", __func__, vrf->vrf_id, vrf->name); + + pbr_map_vrf_update(vrf->info); + + return 0; +} + +static int pbr_vrf_delete(struct vrf *vrf) +{ + DEBUGD(&pbr_dbg_event, "%s: %u (%s)", __func__, vrf->vrf_id, vrf->name); + + /* + * Make sure vrf is always marked disabled first so we handle + * pbr rules using it. + */ + assert(!vrf_is_enabled(vrf)); + + pbr_vrf_free(vrf->info); + vrf->info = NULL; + + return 0; +} + +struct pbr_vrf *pbr_vrf_lookup_by_id(vrf_id_t vrf_id) +{ + struct vrf *vrf; + + vrf = vrf_lookup_by_id(vrf_id); + if (vrf) + return ((struct pbr_vrf *)vrf->info); + + return NULL; +} + +struct pbr_vrf *pbr_vrf_lookup_by_name(const char *name) +{ + struct vrf *vrf; + + if (!name) + name = VRF_DEFAULT_NAME; + + vrf = vrf_lookup_by_name(name); + if (vrf) + return ((struct pbr_vrf *)vrf->info); + + return NULL; +} + +bool pbr_vrf_is_enabled(const struct pbr_vrf *pbr_vrf) +{ + return vrf_is_enabled(pbr_vrf->vrf) ? true : false; +} + +bool pbr_vrf_is_valid(const struct pbr_vrf *pbr_vrf) +{ + if (vrf_is_backend_netns()) + return false; + + if (!pbr_vrf->vrf) + return false; + + return pbr_vrf_is_enabled(pbr_vrf); +} + +void pbr_vrf_init(void) +{ + vrf_init(pbr_vrf_new, pbr_vrf_enable, pbr_vrf_disable, pbr_vrf_delete, + NULL); +} |
