Line data Source code
1 : /* 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 : #include <stddef.h> 17 : 18 : #include <vnet/vnet.h> 19 : #include <vnet/plugin/plugin.h> 20 : #include <l3xc/l3xc.h> 21 : #include <vnet/mpls/mpls_types.h> 22 : #include <vnet/fib/fib_path_list.h> 23 : #include <vnet/fib/fib_api.h> 24 : 25 : #include <vpp/app/version.h> 26 : 27 : #include <vlibapi/api.h> 28 : #include <vlibmemory/api.h> 29 : 30 : /* define message IDs */ 31 : #include <vnet/format_fns.h> 32 : #include <l3xc/l3xc.api_enum.h> 33 : #include <l3xc/l3xc.api_types.h> 34 : 35 : /** 36 : * Base message ID fot the plugin 37 : */ 38 : static u32 l3xc_base_msg_id; 39 : 40 : #define REPLY_MSG_ID_BASE (l3xc_base_msg_id) 41 : #include <vlibapi/api_helper_macros.h> 42 : 43 : static void 44 0 : vl_api_l3xc_plugin_get_version_t_handler (vl_api_l3xc_plugin_get_version_t * 45 : mp) 46 : { 47 : vl_api_l3xc_plugin_get_version_reply_t *rmp; 48 : vl_api_registration_t *rp; 49 : 50 0 : rp = vl_api_client_index_to_registration (mp->client_index); 51 0 : if (rp == 0) 52 0 : return; 53 : 54 0 : rmp = vl_msg_api_alloc (sizeof (*rmp)); 55 0 : rmp->_vl_msg_id = 56 0 : ntohs (VL_API_L3XC_PLUGIN_GET_VERSION_REPLY + l3xc_base_msg_id); 57 0 : rmp->context = mp->context; 58 0 : rmp->major = htonl (L3XC_PLUGIN_VERSION_MAJOR); 59 0 : rmp->minor = htonl (L3XC_PLUGIN_VERSION_MINOR); 60 : 61 0 : vl_api_send_msg (rp, (u8 *) rmp); 62 : } 63 : 64 : static void 65 2 : vl_api_l3xc_update_t_handler (vl_api_l3xc_update_t * mp) 66 : { 67 : vl_api_l3xc_update_reply_t *rmp; 68 2 : fib_route_path_t *paths = NULL, *path; 69 2 : int rv = 0; 70 : u8 pi; 71 : 72 2 : VALIDATE_SW_IF_INDEX (&mp->l3xc); 73 : 74 2 : if (0 == mp->l3xc.n_paths) 75 : { 76 0 : rv = VNET_API_ERROR_INVALID_VALUE; 77 0 : goto done; 78 : } 79 : 80 2 : vec_validate (paths, mp->l3xc.n_paths - 1); 81 : 82 6 : for (pi = 0; pi < mp->l3xc.n_paths; pi++) 83 : { 84 4 : path = &paths[pi]; 85 4 : rv = fib_api_path_decode (&mp->l3xc.paths[pi], path); 86 : 87 4 : if (0 != rv) 88 : { 89 0 : goto done; 90 : } 91 : } 92 : 93 2 : rv = l3xc_update (ntohl (mp->l3xc.sw_if_index), mp->l3xc.is_ip6, paths); 94 : 95 2 : done: 96 2 : vec_free (paths); 97 : 98 2 : BAD_SW_IF_INDEX_LABEL; 99 : 100 2 : REPLY_MACRO2 (VL_API_L3XC_UPDATE_REPLY, ({ rmp->stats_index = 0; })) 101 : } 102 : 103 : static void 104 2 : vl_api_l3xc_del_t_handler (vl_api_l3xc_del_t * mp) 105 : { 106 : vl_api_l3xc_del_reply_t *rmp; 107 2 : int rv = 0; 108 : 109 2 : VALIDATE_SW_IF_INDEX (mp); 110 : 111 2 : rv = l3xc_delete (ntohl (mp->sw_if_index), mp->is_ip6); 112 : 113 2 : BAD_SW_IF_INDEX_LABEL; 114 : 115 2 : REPLY_MACRO (VL_API_L3XC_DEL_REPLY); 116 : } 117 : 118 : typedef struct l3xc_dump_walk_ctx_t_ 119 : { 120 : vl_api_registration_t *rp; 121 : u32 context; 122 : } l3xc_dump_walk_ctx_t; 123 : 124 : static int 125 3 : l3xc_send_details (u32 l3xci, void *args) 126 : { 127 3 : fib_path_encode_ctx_t path_ctx = { 128 : .rpaths = NULL, 129 : }; 130 : vl_api_l3xc_details_t *mp; 131 : l3xc_dump_walk_ctx_t *ctx; 132 : fib_route_path_t *rpath; 133 : vl_api_fib_path_t *fp; 134 : size_t msg_size; 135 : l3xc_t *l3xc; 136 : u8 n_paths; 137 : 138 3 : ctx = args; 139 3 : l3xc = l3xc_get (l3xci); 140 3 : n_paths = fib_path_list_get_n_paths (l3xc->l3xc_pl); 141 3 : msg_size = sizeof (*mp) + sizeof (mp->l3xc.paths[0]) * n_paths; 142 : 143 3 : mp = vl_msg_api_alloc (msg_size); 144 3 : clib_memset (mp, 0, msg_size); 145 3 : mp->_vl_msg_id = ntohs (VL_API_L3XC_DETAILS + l3xc_base_msg_id); 146 : 147 : /* fill in the message */ 148 3 : mp->context = ctx->context; 149 3 : mp->l3xc.n_paths = n_paths; 150 3 : mp->l3xc.sw_if_index = htonl (l3xc->l3xc_sw_if_index); 151 : 152 3 : fib_path_list_walk_w_ext (l3xc->l3xc_pl, NULL, fib_path_encode, &path_ctx); 153 : 154 3 : fp = mp->l3xc.paths; 155 8 : vec_foreach (rpath, path_ctx.rpaths) 156 : { 157 5 : fib_api_path_encode (rpath, fp); 158 5 : fp++; 159 : } 160 : 161 3 : vl_api_send_msg (ctx->rp, (u8 *) mp); 162 : 163 3 : return (1); 164 : } 165 : 166 : static void 167 4 : vl_api_l3xc_dump_t_handler (vl_api_l3xc_dump_t * mp) 168 : { 169 : vl_api_registration_t *rp; 170 : u32 sw_if_index; 171 : 172 4 : rp = vl_api_client_index_to_registration (mp->client_index); 173 4 : if (rp == 0) 174 0 : return; 175 : 176 4 : l3xc_dump_walk_ctx_t ctx = { 177 : .rp = rp, 178 4 : .context = mp->context, 179 : }; 180 : 181 4 : sw_if_index = ntohl (mp->sw_if_index); 182 : 183 4 : if (~0 == sw_if_index) 184 1 : l3xc_walk (l3xc_send_details, &ctx); 185 : else 186 : { 187 : fib_protocol_t fproto; 188 : index_t l3xci; 189 : 190 9 : FOR_EACH_FIB_IP_PROTOCOL (fproto) 191 : { 192 6 : l3xci = l3xc_find (sw_if_index, fproto); 193 : 194 6 : if (INDEX_INVALID != l3xci) 195 1 : l3xc_send_details (l3xci, &ctx); 196 : } 197 : } 198 : } 199 : 200 : #include <l3xc/l3xc.api.c> 201 : static clib_error_t * 202 559 : l3xc_api_init (vlib_main_t * vm) 203 : { 204 : /* Ask for a correctly-sized block of API message decode slots */ 205 559 : l3xc_base_msg_id = setup_message_id_table (); 206 : 207 559 : return 0; 208 : } 209 : 210 1119 : VLIB_INIT_FUNCTION (l3xc_api_init); 211 : 212 : /* *INDENT-OFF* */ 213 : VLIB_PLUGIN_REGISTER () = { 214 : .version = VPP_BUILD_VER, 215 : .description = "L3 Cross-Connect (L3XC)", 216 : }; 217 : /* *INDENT-ON* */ 218 : 219 : /* 220 : * fd.io coding-style-patch-verification: ON 221 : * 222 : * Local Variables: 223 : * eval: (c-set-style "gnu") 224 : * End: 225 : */