Line data Source code
1 : /*
2 : * srv6_end_m_gtp4_e.c
3 : *
4 : * Copyright (c) 2019 Arrcus Inc and/or its affiliates.
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at:
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 :
18 : #include <vnet/vnet.h>
19 : #include <vnet/adj/adj.h>
20 : #include <vnet/plugin/plugin.h>
21 : #include <vpp/app/version.h>
22 : #include <srv6-mobile/mobile.h>
23 :
24 : srv6_end_main_v4_t srv6_end_main_v4;
25 :
26 : static void
27 6 : clb_dpo_lock_srv6_end_m_gtp4_e (dpo_id_t * dpo)
28 : {
29 6 : }
30 :
31 : static void
32 3 : clb_dpo_unlock_srv6_end_m_gtp4_e (dpo_id_t * dpo)
33 : {
34 3 : }
35 :
36 : static u8 *
37 0 : clb_dpo_format_srv6_end_m_gtp4_e (u8 * s, va_list * args)
38 : {
39 0 : index_t index = va_arg (*args, index_t);
40 0 : CLIB_UNUSED (u32 indent) = va_arg (*args, u32);
41 :
42 0 : return (format (s, "SR: dynamic_proxy_index:[%u]", index));
43 : }
44 :
45 : const static dpo_vft_t dpo_vft = {
46 : .dv_lock = clb_dpo_lock_srv6_end_m_gtp4_e,
47 : .dv_unlock = clb_dpo_unlock_srv6_end_m_gtp4_e,
48 : .dv_format = clb_dpo_format_srv6_end_m_gtp4_e,
49 : };
50 :
51 : const static char *const srv6_end_m_gtp4_e_nodes[] = {
52 : "srv6-end-m-gtp4-e",
53 : NULL,
54 : };
55 :
56 : const static char *const *const dpo_nodes[DPO_PROTO_NUM] = {
57 : [DPO_PROTO_IP6] = srv6_end_m_gtp4_e_nodes,
58 : };
59 :
60 : static u8 fn_name[] = "SRv6-End.M.GTP4.E-plugin";
61 : static u8 keyword_str[] = "end.m.gtp4.e";
62 : static u8 def_str[] =
63 : "Endpoint function with encapsulation for IPv4/GTP tunnel";
64 : static u8 param_str[] = "";
65 :
66 : static u8 *
67 1 : clb_format_srv6_end_m_gtp4_e (u8 * s, va_list * args)
68 : {
69 1 : srv6_end_gtp4_e_param_t *ls_mem = va_arg (*args, void *);
70 :
71 1 : s = format (s, "SRv6 End gtp4.e\n");
72 :
73 1 : s = format (s, "\tIPv4 address position: %d\n", ls_mem->v4src_position);
74 :
75 1 : s = format (s, "\tIPv4 source address: %U\n", format_ip4_address,
76 : &ls_mem->v4src_addr);
77 :
78 1 : s = format (s, "\tFib Table %d\n", ls_mem->fib_table);
79 :
80 1 : return s;
81 : }
82 :
83 : static uword
84 3 : clb_unformat_srv6_end_m_gtp4_e (unformat_input_t * input, va_list * args)
85 : {
86 3 : void **plugin_mem_p = va_arg (*args, void **);
87 : srv6_end_gtp4_e_param_t *ls_mem;
88 : ip4_address_t v4src_addr;
89 3 : u32 v4src_position = 0;
90 : u32 fib_table;
91 3 : bool config = false;
92 :
93 3 : memset (&v4src_addr, 0, sizeof (ip4_address_t));
94 :
95 4 : while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
96 : {
97 3 : if (unformat (input, "end.m.gtp4.e v4src_position %d fib-table %d",
98 : &v4src_position, &fib_table))
99 : {
100 1 : config = true;
101 : }
102 2 : else if (unformat (input, "end.m.gtp4.e v4src_addr %U fib-table %d",
103 : unformat_ip4_address, &v4src_addr, &fib_table))
104 : {
105 0 : config = true;
106 : }
107 : else
108 : {
109 2 : return 0;
110 : }
111 : }
112 :
113 1 : if (!config)
114 0 : return 0;
115 :
116 1 : ls_mem = clib_mem_alloc (sizeof *ls_mem);
117 1 : clib_memset (ls_mem, 0, sizeof *ls_mem);
118 1 : *plugin_mem_p = ls_mem;
119 :
120 1 : ls_mem->v4src_position = v4src_position;
121 1 : memcpy (&ls_mem->v4src_addr, &v4src_addr, sizeof (ip4_address_t));
122 :
123 1 : ls_mem->fib_table = fib_table;
124 1 : ls_mem->fib4_index = ip4_fib_index_from_table_id (fib_table);
125 1 : ls_mem->fib6_index = ip6_fib_index_from_table_id (fib_table);
126 :
127 1 : return 1;
128 : }
129 :
130 : static int
131 1 : clb_creation_srv6_end_m_gtp4_e (ip6_sr_localsid_t * localsid)
132 : {
133 1 : return 0;
134 : }
135 :
136 : static int
137 0 : clb_removal_srv6_end_m_gtp4_e (ip6_sr_localsid_t * localsid)
138 : {
139 : srv6_end_gtp4_e_param_t *ls_mem;
140 :
141 0 : ls_mem = localsid->plugin_mem;
142 :
143 0 : clib_mem_free (ls_mem);
144 :
145 0 : return 0;
146 : }
147 :
148 : static clib_error_t *
149 575 : srv6_end_m_gtp4_e_init (vlib_main_t * vm)
150 : {
151 575 : srv6_end_main_v4_t *sm = &srv6_end_main_v4;
152 575 : ip4_header_t *ip4 = &sm->cache_hdr.ip4;
153 575 : udp_header_t *udp = &sm->cache_hdr.udp;
154 575 : gtpu_header_t *gtpu = &sm->cache_hdr.gtpu;
155 : dpo_type_t dpo_type;
156 : vlib_node_t *node;
157 : int rc;
158 :
159 575 : sm->vlib_main = vm;
160 575 : sm->vnet_main = vnet_get_main ();
161 :
162 575 : node = vlib_get_node_by_name (vm, (u8 *) "srv6-end-m-gtp4-e");
163 575 : sm->end_m_gtp4_e_node_index = node->index;
164 :
165 575 : node = vlib_get_node_by_name (vm, (u8 *) "error-drop");
166 575 : sm->error_node_index = node->index;
167 :
168 575 : sm->dst_p_len = 32;
169 575 : sm->src_p_len = 64;
170 :
171 : // clear the pre cached packet
172 575 : clib_memset_u8 (ip4, 0, sizeof (ip4_gtpu_header_t));
173 :
174 : // set defaults
175 575 : ip4->ip_version_and_header_length = 0x45;
176 575 : ip4->protocol = IP_PROTOCOL_UDP;
177 575 : ip4->ttl = 64;
178 :
179 575 : udp->dst_port = clib_host_to_net_u16 (SRV6_GTP_UDP_DST_PORT);
180 :
181 575 : gtpu->ver_flags = GTPU_V1_VER | GTPU_PT_GTP;
182 575 : gtpu->type = GTPU_TYPE_GTPU;
183 : //
184 :
185 575 : dpo_type = dpo_register_new_type (&dpo_vft, dpo_nodes);
186 :
187 575 : rc = sr_localsid_register_function (vm, fn_name, keyword_str, def_str, param_str, 32, //prefix len
188 : &dpo_type,
189 : clb_format_srv6_end_m_gtp4_e,
190 : clb_unformat_srv6_end_m_gtp4_e,
191 : clb_creation_srv6_end_m_gtp4_e,
192 : clb_removal_srv6_end_m_gtp4_e);
193 575 : if (rc < 0)
194 0 : clib_error_return (0, "SRv6 Endpoint GTP4.E LocalSID function"
195 : "couldn't be registered");
196 575 : return 0;
197 : }
198 :
199 : /* *INDENT-OFF* */
200 14399 : VNET_FEATURE_INIT (srv6_end_m_gtp4_e, static) =
201 : {
202 : .arc_name = "ip6-unicast",
203 : .node_name = "srv6-end-m-gtp4-e",
204 : .runs_before = 0,
205 : };
206 :
207 1151 : VLIB_INIT_FUNCTION (srv6_end_m_gtp4_e_init);
208 :
209 : VLIB_PLUGIN_REGISTER () = {
210 : .version = VPP_BUILD_VER,
211 : .description = "SRv6 GTP Endpoint Functions",
212 : };
213 : /* *INDENT-ON* */
214 :
215 : /*
216 : * fd.io coding-style-patch-verification: ON
217 : *
218 : * Local Variables:
219 : * eval: (c-set-style "gnu")
220 : * End:
221 : */
|