summaryrefslogtreecommitdiffstats
path: root/src/plugins/abf/abf_policy.h
blob: 7d890abed730d011441030a739d1a64802dbad09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
 * Copyright (c) 2017 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __ABF_H__
#define __ABF_H__

#include <vnet/fib/fib_node.h>

#define ABF_PLUGIN_VERSION_MAJOR 1
#define ABF_PLUGIN_VERSION_MINOR 0

/**
 * An ACL based Forwarding 'policy'.
 * This comprises the ACL index to match against and the forwarding
 * path to take if the match is successful.
 *
 * ABF policies are then 'attached' to interfaces. An input feature
 * will run through the list of policies a match will divert the packet,
 * if all miss then we continues down the interface's feature arc
 */
typedef struct abf_policy_t_
{
  /**
   * Linkage into the FIB graph
   */
  fib_node_t ap_node;

  /**
   * ACL index to match
   */
  u32 ap_acl;

  /**
   * The path-list describing how to forward in case of a match
   */
  fib_node_index_t ap_pl;

  /**
   * Sibling index on the path-list
   */
  u32 ap_sibling;

  /**
   * The policy ID - as configured by the client
   */
  u32 ap_id;
} abf_policy_t;

/**
 * Get an ABF object from its VPP index
 */
extern abf_policy_t *abf_policy_get (index_t index);

/**
 * Find a ABF object from the client's policy ID
 *
 * @param policy_id Client's defined policy ID
 * @return VPP's object index
 */
extern index_t abf_policy_find (u32 policy_id);

/**
 * The FIB node type for ABF policies
 */
extern fib_node_type_t abf_policy_fib_node_type;

/**
 * Create or update an ABF Policy
 *
 * @param policy_id User defined Policy ID
 * @param acl_index The ACL the policy with match on
 * @param rpaths The set of paths to add to the forwarding set
 * @return error code
 */
extern int abf_policy_update (u32 policy_id,
			      u32 acl_index, const fib_route_path_t * rpaths);

/**
 * Delete paths from an ABF Policy. If no more paths exist, the policy
 * is deleted.
 *
 * @param policy_id User defined Policy ID
 * @param rpaths The set of paths to forward remove
 */
extern int abf_policy_delete (u32 policy_id, const fib_route_path_t * rpaths);

/**
 * Callback function invoked during a walk of all policies
 */
typedef int (*abf_policy_walk_cb_t) (index_t index, void *ctx);

/**
 * Walk/visit each of the ABF policies
 */
extern void abf_policy_walk (abf_policy_walk_cb_t cb, void *ctx);


/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */

#endif
n class="o">+ l3xc_base_msg_id); rmp->context = mp->context; rmp->major = htonl (L3XC_PLUGIN_VERSION_MAJOR); rmp->minor = htonl (L3XC_PLUGIN_VERSION_MINOR); vl_api_send_msg (rp, (u8 *) rmp); } static void vl_api_l3xc_update_t_handler (vl_api_l3xc_update_t * mp) { vl_api_l3xc_update_reply_t *rmp; fib_route_path_t *paths = NULL, *path; int rv = 0; u8 pi; VALIDATE_SW_IF_INDEX (&mp->l3xc); if (0 == mp->l3xc.n_paths) { rv = VNET_API_ERROR_INVALID_VALUE; goto done; } vec_validate (paths, mp->l3xc.n_paths - 1); for (pi = 0; pi < mp->l3xc.n_paths; pi++) { path = &paths[pi]; rv = fib_api_path_decode (&mp->l3xc.paths[pi], path); if (0 != rv) { goto done; } } rv = l3xc_update (ntohl (mp->l3xc.sw_if_index), mp->l3xc.is_ip6, paths); done: vec_free (paths); BAD_SW_IF_INDEX_LABEL; /* *INDENT-OFF* */ REPLY_MACRO2 (VL_API_L3XC_UPDATE_REPLY + l3xc_base_msg_id, ({ rmp->stats_index = 0; })) /* *INDENT-ON* */ } static void vl_api_l3xc_del_t_handler (vl_api_l3xc_del_t * mp) { vl_api_l3xc_del_reply_t *rmp; int rv = 0; VALIDATE_SW_IF_INDEX (mp); rv = l3xc_delete (ntohl (mp->sw_if_index), mp->is_ip6); BAD_SW_IF_INDEX_LABEL; REPLY_MACRO (VL_API_L3XC_DEL_REPLY + l3xc_base_msg_id); } typedef struct l3xc_dump_walk_ctx_t_ { vl_api_registration_t *rp; u32 context; } l3xc_dump_walk_ctx_t; static int l3xc_send_details (u32 l3xci, void *args) { fib_path_encode_ctx_t path_ctx = { .rpaths = NULL, }; vl_api_l3xc_details_t *mp; l3xc_dump_walk_ctx_t *ctx; fib_route_path_t *rpath; vl_api_fib_path_t *fp; size_t msg_size; l3xc_t *l3xc; u8 n_paths; ctx = args; l3xc = l3xc_get (l3xci); n_paths = fib_path_list_get_n_paths (l3xc->l3xc_pl); msg_size = sizeof (*mp) + sizeof (mp->l3xc.paths[0]) * n_paths; mp = vl_msg_api_alloc (msg_size); clib_memset (mp, 0, msg_size); mp->_vl_msg_id = ntohs (VL_API_L3XC_DETAILS + l3xc_base_msg_id); /* fill in the message */ mp->context = ctx->context; mp->l3xc.n_paths = n_paths; mp->l3xc.sw_if_index = htonl (l3xc->l3xc_sw_if_index); fib_path_list_walk_w_ext (l3xc->l3xc_pl, NULL, fib_path_encode, &path_ctx); fp = mp->l3xc.paths; vec_foreach (rpath, path_ctx.rpaths) { fib_api_path_encode (rpath, fp); fp++; } vl_api_send_msg (ctx->rp, (u8 *) mp); return (1); } static void vl_api_l3xc_dump_t_handler (vl_api_l3xc_dump_t * mp) { vl_api_registration_t *rp; u32 sw_if_index; rp = vl_api_client_index_to_registration (mp->client_index); if (rp == 0) return; l3xc_dump_walk_ctx_t ctx = { .rp = rp, .context = mp->context, }; sw_if_index = ntohl (mp->sw_if_index); if (~0 == sw_if_index) l3xc_walk (l3xc_send_details, &ctx); else { fib_protocol_t fproto; index_t l3xci; FOR_EACH_FIB_IP_PROTOCOL (fproto) { l3xci = l3xc_find (sw_if_index, fproto); if (INDEX_INVALID != l3xci) l3xc_send_details (l3xci, &ctx); } } } #include <l3xc/l3xc.api.c> static clib_error_t * l3xc_api_init (vlib_main_t * vm) { /* Ask for a correctly-sized block of API message decode slots */ l3xc_base_msg_id = setup_message_id_table (); return 0; } VLIB_INIT_FUNCTION (l3xc_api_init); /* *INDENT-OFF* */ VLIB_PLUGIN_REGISTER () = { .version = VPP_BUILD_VER, .description = "L3 Cross-Connect (L3XC)", }; /* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */