]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
be3b67b5 SW |
2 | /* |
3 | * PBR - vrf code | |
4 | * Copyright (C) 2019 Cumulus Networks, Inc. | |
5 | * Stephen Worley | |
be3b67b5 SW |
6 | */ |
7 | #include <zebra.h> | |
8 | ||
9 | #include "vrf.h" | |
10 | ||
11 | #include "pbr_vrf.h" | |
12 | #include "pbr_memory.h" | |
13 | #include "pbr_map.h" | |
14 | #include "pbr_debug.h" | |
fcf29c69 | 15 | #include "pbr_nht.h" |
0e7d7358 | 16 | #include "pbr_zebra.h" |
be3b67b5 | 17 | |
bf8d3d6a | 18 | DEFINE_MTYPE_STATIC(PBRD, PBR_MAP_VRF, "PBR Map VRF"); |
be3b67b5 SW |
19 | |
20 | static struct pbr_vrf *pbr_vrf_alloc(void) | |
21 | { | |
22 | struct pbr_vrf *pbr_vrf; | |
23 | ||
24 | pbr_vrf = XCALLOC(MTYPE_PBR_MAP_VRF, sizeof(struct pbr_vrf)); | |
25 | ||
26 | return pbr_vrf; | |
27 | } | |
28 | ||
29 | static void pbr_vrf_free(struct pbr_vrf *pbr_vrf) | |
30 | { | |
31 | XFREE(MTYPE_PBR_MAP_VRF, pbr_vrf); | |
32 | } | |
33 | ||
34 | static int pbr_vrf_new(struct vrf *vrf) | |
35 | { | |
36 | struct pbr_vrf *pbr_vrf; | |
37 | ||
38 | DEBUGD(&pbr_dbg_event, "%s: %u (%s)", __func__, vrf->vrf_id, vrf->name); | |
39 | ||
40 | pbr_vrf = pbr_vrf_alloc(); | |
41 | vrf->info = pbr_vrf; | |
42 | pbr_vrf->vrf = vrf; | |
43 | ||
44 | return 0; | |
45 | } | |
46 | ||
47 | static int pbr_vrf_enable(struct vrf *vrf) | |
48 | { | |
49 | DEBUGD(&pbr_dbg_event, "%s: %u (%s)", __func__, vrf->vrf_id, vrf->name); | |
50 | ||
fcf29c69 | 51 | pbr_nht_vrf_update(vrf->info); |
be3b67b5 SW |
52 | pbr_map_vrf_update(vrf->info); |
53 | ||
54 | return 0; | |
55 | } | |
56 | ||
57 | static int pbr_vrf_disable(struct vrf *vrf) | |
58 | { | |
59 | DEBUGD(&pbr_dbg_event, "%s: %u (%s)", __func__, vrf->vrf_id, vrf->name); | |
60 | ||
61 | pbr_map_vrf_update(vrf->info); | |
62 | ||
63 | return 0; | |
64 | } | |
65 | ||
66 | static int pbr_vrf_delete(struct vrf *vrf) | |
67 | { | |
68 | DEBUGD(&pbr_dbg_event, "%s: %u (%s)", __func__, vrf->vrf_id, vrf->name); | |
69 | ||
70 | /* | |
71 | * Make sure vrf is always marked disabled first so we handle | |
72 | * pbr rules using it. | |
73 | */ | |
74 | assert(!vrf_is_enabled(vrf)); | |
75 | ||
76 | pbr_vrf_free(vrf->info); | |
77 | vrf->info = NULL; | |
78 | ||
79 | return 0; | |
80 | } | |
81 | ||
be3b67b5 SW |
82 | struct pbr_vrf *pbr_vrf_lookup_by_name(const char *name) |
83 | { | |
84 | struct vrf *vrf; | |
85 | ||
86 | if (!name) | |
87 | name = VRF_DEFAULT_NAME; | |
88 | ||
89 | vrf = vrf_lookup_by_name(name); | |
90 | if (vrf) | |
91 | return ((struct pbr_vrf *)vrf->info); | |
92 | ||
93 | return NULL; | |
94 | } | |
95 | ||
96 | bool pbr_vrf_is_enabled(const struct pbr_vrf *pbr_vrf) | |
97 | { | |
98 | return vrf_is_enabled(pbr_vrf->vrf) ? true : false; | |
99 | } | |
100 | ||
101 | bool pbr_vrf_is_valid(const struct pbr_vrf *pbr_vrf) | |
102 | { | |
103 | if (vrf_is_backend_netns()) | |
104 | return false; | |
105 | ||
106 | if (!pbr_vrf->vrf) | |
107 | return false; | |
108 | ||
109 | return pbr_vrf_is_enabled(pbr_vrf); | |
110 | } | |
111 | ||
112 | void pbr_vrf_init(void) | |
113 | { | |
ac2cb9bf | 114 | vrf_init(pbr_vrf_new, pbr_vrf_enable, pbr_vrf_disable, pbr_vrf_delete); |
be3b67b5 | 115 | } |
0e7d7358 DS |
116 | |
117 | void pbr_vrf_terminate(void) | |
118 | { | |
119 | struct vrf *vrf; | |
120 | struct interface *ifp; | |
121 | ||
122 | RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { | |
123 | FOR_ALL_INTERFACES (vrf, ifp) | |
124 | pbr_if_del(ifp); | |
125 | } | |
126 | } |