blob: d21f52a4833c9b22b53396d4a173f7561f349a54 [file] [log] [blame]
Neale Ranns32e1c012016-11-22 17:07:28 +00001/*
2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15/**
16 * @brief
17 *
18 */
19
20#ifndef __REPLICATE_DPO_H__
21#define __REPLICATE_DPO_H__
22
23#include <vlib/vlib.h>
24#include <vnet/ip/lookup.h>
25#include <vnet/dpo/dpo.h>
26#include <vnet/dpo/load_balance.h>
27#include <vnet/fib/fib_types.h>
Neale Ranns0f26c5a2017-03-01 15:12:11 -080028#include <vnet/mpls/mpls_types.h>
Neale Ranns32e1c012016-11-22 17:07:28 +000029
30/**
31 * replicate main
32 */
33typedef struct replicate_main_t_
34{
35 vlib_combined_counter_main_t repm_counters;
Damjan Marionc47ed032017-01-25 14:18:03 +010036
37 /* per-cpu vector of cloned packets */
38 u32 **clones;
Neale Ranns32e1c012016-11-22 17:07:28 +000039} replicate_main_t;
40
41extern replicate_main_t replicate_main;
42
43/**
Benoît Gannee211ac42023-02-21 16:09:47 +010044 * The number of buckets that a replicate object can have
45 * This must not overflow the rep_n_buckets field
46 */
47#define REP_MAX_BUCKETS 1024
48
49/**
Neale Ranns32e1c012016-11-22 17:07:28 +000050 * The number of buckets that a load-balance object can have and still
51 * fit in one cache-line
52 */
53#define REP_NUM_INLINE_BUCKETS 4
54
55/**
Neale Ranns9e829a82018-12-17 05:50:32 -080056 * Flags on the replicate DPO
57 */
58typedef enum replicate_flags_t_
59{
60 REPLICATE_FLAGS_NONE,
61 REPLICATE_FLAGS_HAS_LOCAL,
62} __clib_packed replicate_flags_t;
63
64/**
Neale Ranns32e1c012016-11-22 17:07:28 +000065 * The FIB DPO provieds;
66 * - load-balancing over the next DPOs in the chain/graph
67 * - per-route counters
68 */
69typedef struct replicate_t_ {
70 /**
Dave Baracheb987d32018-05-03 08:26:39 -040071 * required for pool_get_aligned.
72 * memebers used in the switch path come first!
73 */
74 CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);
75
76 /**
Neale Ranns2303cb12018-02-21 04:57:17 -080077 * number of buckets in the replicate.
Neale Ranns32e1c012016-11-22 17:07:28 +000078 */
79 u16 rep_n_buckets;
80
81 /**
82 * The protocol of packets that traverse this REP.
83 * need in combination with the flow hash config to determine how to hash.
84 * u8.
85 */
86 dpo_proto_t rep_proto;
87
88 /**
Neale Ranns9e829a82018-12-17 05:50:32 -080089 * Flags specifying the replicate properties/behaviour
90 */
91 replicate_flags_t rep_flags;
92
93 /**
Neale Ranns32e1c012016-11-22 17:07:28 +000094 * The number of locks, which is approximately the number of users,
95 * of this load-balance.
96 * Load-balance objects of via-entries are heavily shared by recursives,
97 * so the lock count is a u32.
98 */
99 u32 rep_locks;
100
101 /**
102 * Vector of buckets containing the next DPOs, sized as repo_num
103 */
104 dpo_id_t *rep_buckets;
105
106 /**
107 * The rest of the cache line is used for buckets. In the common case
108 * where there there are less than 4 buckets, then the buckets are
109 * on the same cachlie and we save ourselves a pointer dereferance in
110 * the data-path.
111 */
112 dpo_id_t rep_buckets_inline[REP_NUM_INLINE_BUCKETS];
113} replicate_t;
114
115STATIC_ASSERT(sizeof(replicate_t) <= CLIB_CACHE_LINE_BYTES,
Lijian.Zhang33af8c12019-09-16 16:22:36 +0800116 "A replicate object size exceeds one cacheline");
Benoît Gannee211ac42023-02-21 16:09:47 +0100117STATIC_ASSERT (REP_MAX_BUCKETS <= CLIB_U16_MAX,
118 "Too many buckets for replicate object");
Neale Ranns32e1c012016-11-22 17:07:28 +0000119
120/**
121 * Flags controlling load-balance formatting/display
122 */
123typedef enum replicate_format_flags_t_ {
124 REPLICATE_FORMAT_NONE,
125 REPLICATE_FORMAT_DETAIL = (1 << 0),
126} replicate_format_flags_t;
127
128extern index_t replicate_create(u32 num_buckets,
129 dpo_proto_t rep_proto);
130extern void replicate_multipath_update(
131 const dpo_id_t *dpo,
132 load_balance_path_t *next_hops);
133
134extern void replicate_set_bucket(index_t repi,
Neale Ranns2303cb12018-02-21 04:57:17 -0800135 u32 bucket,
136 const dpo_id_t *next);
Neale Ranns32e1c012016-11-22 17:07:28 +0000137
138extern u8* format_replicate(u8 * s, va_list * args);
139
140extern const dpo_id_t *replicate_get_bucket(index_t repi,
Neale Ranns2303cb12018-02-21 04:57:17 -0800141 u32 bucket);
Neale Ranns32e1c012016-11-22 17:07:28 +0000142extern int replicate_is_drop(const dpo_id_t *dpo);
143
Neale Ranns2303cb12018-02-21 04:57:17 -0800144extern u16 replicate_n_buckets(index_t repi);
145
Neale Ranns9e829a82018-12-17 05:50:32 -0800146extern index_t replicate_dup(replicate_flags_t flags,
147 index_t repi);
148
Neale Ranns32e1c012016-11-22 17:07:28 +0000149/**
150 * The encapsulation breakages are for fast DP access
151 */
152extern replicate_t *replicate_pool;
153static inline replicate_t*
154replicate_get (index_t repi)
155{
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800156 repi &= ~MPLS_IS_REPLICATE;
Neale Ranns32e1c012016-11-22 17:07:28 +0000157 return (pool_elt_at_index(replicate_pool, repi));
158}
159
160#define REP_HAS_INLINE_BUCKETS(_rep) \
161 ((_rep)->rep_n_buckets <= REP_NUM_INLINE_BUCKETS)
162
163static inline const dpo_id_t *
164replicate_get_bucket_i (const replicate_t *rep,
165 u32 bucket)
166{
167 ASSERT(bucket < rep->rep_n_buckets);
168
169 if (PREDICT_TRUE(REP_HAS_INLINE_BUCKETS(rep)))
170 {
171 return (&rep->rep_buckets_inline[bucket]);
172 }
173 else
174 {
175 return (&rep->rep_buckets[bucket]);
176 }
177}
178
179extern void replicate_module_init(void);
180
181#endif