Line data Source code
1 : /* 2 : *------------------------------------------------------------------ 3 : * gre_api.c - gre api 4 : * 5 : * Copyright (c) 2016 Cisco and/or its affiliates. 6 : * Licensed under the Apache License, Version 2.0 (the "License"); 7 : * you may not use this file except in compliance with the License. 8 : * You may obtain a copy of the License at: 9 : * 10 : * http://www.apache.org/licenses/LICENSE-2.0 11 : * 12 : * Unless required by applicable law or agreed to in writing, software 13 : * distributed under the License is distributed on an "AS IS" BASIS, 14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 : * See the License for the specific language governing permissions and 16 : * limitations under the License. 17 : *------------------------------------------------------------------ 18 : */ 19 : 20 : #include <vnet/vnet.h> 21 : #include <vlibmemory/api.h> 22 : 23 : #include <vnet/interface.h> 24 : #include <vnet/api_errno.h> 25 : 26 : #include <gre/gre.h> 27 : #include <vnet/fib/fib_table.h> 28 : #include <vnet/tunnel/tunnel_types_api.h> 29 : #include <vnet/ip/ip_types_api.h> 30 : 31 : #include <gre/gre.api_enum.h> 32 : #include <gre/gre.api_types.h> 33 : 34 : #define REPLY_MSG_ID_BASE gre_main.msg_id_base 35 : #include <vlibapi/api_helper_macros.h> 36 : 37 : static int 38 95 : gre_tunnel_type_decode (vl_api_gre_tunnel_type_t in, gre_tunnel_type_t *out) 39 : { 40 95 : switch (in) 41 : { 42 : #define _(n, v) \ 43 : case GRE_API_TUNNEL_TYPE_##n: \ 44 : *out = GRE_TUNNEL_TYPE_##n; \ 45 : return (0); 46 95 : foreach_gre_tunnel_type 47 : #undef _ 48 : } 49 : 50 0 : return (VNET_API_ERROR_INVALID_VALUE); 51 : } 52 : 53 : static vl_api_gre_tunnel_type_t 54 36 : gre_tunnel_type_encode (gre_tunnel_type_t in) 55 : { 56 36 : vl_api_gre_tunnel_type_t out = GRE_API_TUNNEL_TYPE_L3; 57 : 58 36 : switch (in) 59 : { 60 : #define _(n, v) \ 61 : case GRE_TUNNEL_TYPE_##n: \ 62 : out = GRE_API_TUNNEL_TYPE_##n; \ 63 : break; 64 36 : foreach_gre_tunnel_type 65 : #undef _ 66 : } 67 : 68 36 : return (out); 69 : } 70 : 71 : static void 72 95 : vl_api_gre_tunnel_add_del_t_handler (vl_api_gre_tunnel_add_del_t *mp) 73 : { 74 95 : vnet_gre_tunnel_add_del_args_t _a = {}, *a = &_a; 75 : vl_api_gre_tunnel_add_del_reply_t *rmp; 76 : tunnel_encap_decap_flags_t flags; 77 95 : u32 sw_if_index = ~0; 78 : ip46_type_t itype[2]; 79 95 : int rv = 0; 80 : 81 95 : itype[0] = ip_address_decode (&mp->tunnel.src, &a->src); 82 95 : itype[1] = ip_address_decode (&mp->tunnel.dst, &a->dst); 83 : 84 95 : if (itype[0] != itype[1]) 85 : { 86 0 : rv = VNET_API_ERROR_INVALID_PROTOCOL; 87 0 : goto out; 88 : } 89 : 90 95 : if (ip46_address_is_equal (&a->src, &a->dst)) 91 : { 92 0 : rv = VNET_API_ERROR_SAME_SRC_DST; 93 0 : goto out; 94 : } 95 : 96 95 : rv = gre_tunnel_type_decode (mp->tunnel.type, &a->type); 97 : 98 95 : if (rv) 99 0 : goto out; 100 : 101 95 : rv = tunnel_mode_decode (mp->tunnel.mode, &a->mode); 102 : 103 95 : if (rv) 104 0 : goto out; 105 : 106 95 : rv = tunnel_encap_decap_flags_decode (mp->tunnel.flags, &flags); 107 : 108 95 : if (rv) 109 0 : goto out; 110 : 111 95 : a->is_add = mp->is_add; 112 95 : a->is_ipv6 = (itype[0] == IP46_TYPE_IP6); 113 95 : a->instance = ntohl (mp->tunnel.instance); 114 95 : a->session_id = ntohs (mp->tunnel.session_id); 115 95 : a->outer_table_id = ntohl (mp->tunnel.outer_table_id); 116 95 : a->flags = flags; 117 : 118 95 : rv = vnet_gre_tunnel_add_del (a, &sw_if_index); 119 : 120 95 : out: 121 : /* *INDENT-OFF* */ 122 95 : REPLY_MACRO2 (VL_API_GRE_TUNNEL_ADD_DEL_REPLY, 123 : ({ rmp->sw_if_index = ntohl (sw_if_index); })); 124 : /* *INDENT-ON* */ 125 : } 126 : 127 : static void 128 36 : send_gre_tunnel_details (gre_tunnel_t *t, vl_api_gre_tunnel_dump_t *mp) 129 : { 130 : vl_api_gre_tunnel_details_t *rmp; 131 : 132 : /* *INDENT-OFF* */ 133 36 : REPLY_MACRO_DETAILS2 ( 134 : VL_API_GRE_TUNNEL_DETAILS, ({ 135 : ip_address_encode (&t->tunnel_src, IP46_TYPE_ANY, &rmp->tunnel.src); 136 : ip_address_encode (&t->tunnel_dst.fp_addr, IP46_TYPE_ANY, 137 : &rmp->tunnel.dst); 138 : 139 : rmp->tunnel.outer_table_id = htonl ( 140 : fib_table_get_table_id (t->outer_fib_index, t->tunnel_dst.fp_proto)); 141 : 142 : rmp->tunnel.type = gre_tunnel_type_encode (t->type); 143 : rmp->tunnel.mode = tunnel_mode_encode (t->mode); 144 : rmp->tunnel.flags = tunnel_encap_decap_flags_encode (t->flags); 145 : rmp->tunnel.instance = htonl (t->user_instance); 146 : rmp->tunnel.sw_if_index = htonl (t->sw_if_index); 147 : rmp->tunnel.session_id = htons (t->session_id); 148 : })); 149 : /* *INDENT-ON* */ 150 : } 151 : 152 : static void 153 83 : vl_api_gre_tunnel_dump_t_handler (vl_api_gre_tunnel_dump_t *mp) 154 : { 155 : vl_api_registration_t *reg; 156 83 : gre_main_t *gm = &gre_main; 157 : gre_tunnel_t *t; 158 : u32 sw_if_index; 159 : 160 83 : reg = vl_api_client_index_to_registration (mp->client_index); 161 83 : if (!reg) 162 0 : return; 163 : 164 83 : sw_if_index = ntohl (mp->sw_if_index); 165 : 166 83 : if (~0 == sw_if_index) 167 : { 168 : /* *INDENT-OFF* */ 169 0 : pool_foreach (t, gm->tunnels) 170 : { 171 0 : send_gre_tunnel_details (t, mp); 172 : } 173 : /* *INDENT-ON* */ 174 : } 175 : 176 : else 177 : { 178 83 : if ((sw_if_index >= vec_len (gm->tunnel_index_by_sw_if_index)) || 179 83 : (~0 == gm->tunnel_index_by_sw_if_index[sw_if_index])) 180 : { 181 47 : return; 182 : } 183 36 : t = &gm->tunnels[gm->tunnel_index_by_sw_if_index[sw_if_index]]; 184 36 : send_gre_tunnel_details (t, mp); 185 : } 186 : } 187 : 188 : /* 189 : * gre_api_hookup 190 : * Add vpe's API message handlers to the table. 191 : * vlib has already mapped shared memory and 192 : * added the client registration handlers. 193 : * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process() 194 : */ 195 : /* API definitions */ 196 : #include <vnet/format_fns.h> 197 : #include <gre/gre.api.c> 198 : 199 : static clib_error_t * 200 559 : gre_api_hookup (vlib_main_t *vm) 201 : { 202 : /* 203 : * Set up the (msg_name, crc, message-id) table 204 : */ 205 559 : gre_main.msg_id_base = setup_message_id_table (); 206 : 207 559 : return 0; 208 : } 209 : 210 1119 : VLIB_API_INIT_FUNCTION (gre_api_hookup); 211 : 212 : /* 213 : * fd.io coding-style-patch-verification: ON 214 : * 215 : * Local Variables: 216 : * eval: (c-set-style "gnu") 217 : * End: 218 : */