Line data Source code
1 : /*
2 : * srv6_t_m_gtp4_dt.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/fib/fib_table.h>
21 : #include <vnet/plugin/plugin.h>
22 : #include <vpp/app/version.h>
23 : #include <srv6-mobile/mobile.h>
24 :
25 : srv6_t_main_v4_dt_t srv6_t_main_v4_dt;
26 :
27 : static void
28 0 : clb_dpo_lock_srv6_t_m_gtp4_dt (dpo_id_t * dpo)
29 : {
30 0 : }
31 :
32 : static void
33 0 : clb_dpo_unlock_srv6_t_m_gtp4_dt (dpo_id_t * dpo)
34 : {
35 0 : }
36 :
37 : static u8 *
38 0 : clb_dpo_format_srv6_t_m_gtp4_dt (u8 * s, va_list * args)
39 : {
40 0 : index_t index = va_arg (*args, index_t);
41 0 : CLIB_UNUSED (u32 indent) = va_arg (*args, u32);
42 :
43 0 : return (format (s, "SR: dynamic_proxy_index:[%u]", index));
44 : }
45 :
46 : const static dpo_vft_t dpo_vft = {
47 : .dv_lock = clb_dpo_lock_srv6_t_m_gtp4_dt,
48 : .dv_unlock = clb_dpo_unlock_srv6_t_m_gtp4_dt,
49 : .dv_format = clb_dpo_format_srv6_t_m_gtp4_dt,
50 : };
51 :
52 : const static char *const srv6_t_m_gtp4_dt_nodes[] = {
53 : "srv6-t-m-gtp4-dt",
54 : NULL,
55 : };
56 :
57 : const static char *const srv6_t_m_gtp4_dt_v6_nodes[] = {
58 : "error-drop",
59 : NULL,
60 : };
61 :
62 : const static char *const *const dpo_nodes[DPO_PROTO_NUM] = {
63 : [DPO_PROTO_IP6] = srv6_t_m_gtp4_dt_v6_nodes,
64 : [DPO_PROTO_IP4] = srv6_t_m_gtp4_dt_nodes,
65 : };
66 :
67 : static u8 fn_name[] = "SRv6-T.M.GTP4.DT-plugin";
68 : static u8 keyword_str[] = "t.m.gtp4.dt";
69 : static u8 def_str[] = "Transit function with DT for IPv4/GTP tunnel";
70 : static u8 param_str[] = "fib-index <index> [local-fib-table <index>]";
71 :
72 : static u8 *
73 0 : clb_format_srv6_t_m_gtp4_dt (u8 * s, va_list * args)
74 : {
75 0 : srv6_t_gtp4_dt_param_t *ls_mem = va_arg (*args, void *);
76 :
77 0 : s = format (s, "SRv6 Transit gtp4.dt\n\t");
78 :
79 0 : if (ls_mem->type == SRV6_GTP4_DT4)
80 0 : s = format (s, " Type GTP4.DT4 fib-table %u\n", ls_mem->fib4_index);
81 0 : else if (ls_mem->type == SRV6_GTP4_DT6)
82 0 : s = format (s, " Type GTP4.DT6, fib-table %u, local-fib-table %u\n",
83 : ls_mem->fib6_index, ls_mem->local_fib_index);
84 0 : else if (ls_mem->type == SRV6_GTP4_DT46)
85 0 : s = format (s, " Type GTP4.DT46, fib-table %u, local-fib-table %u\n",
86 : ls_mem->fib6_index, ls_mem->local_fib_index);
87 : else
88 0 : s = format (s, "\n");
89 :
90 0 : return s;
91 : }
92 :
93 : static uword
94 0 : clb_unformat_srv6_t_m_gtp4_dt (unformat_input_t * input, va_list * args)
95 : {
96 0 : void **plugin_mem_p = va_arg (*args, void **);
97 : srv6_t_gtp4_dt_param_t *ls_mem;
98 0 : u32 fib_index = 0;
99 0 : u32 local_fib_index = 0;
100 : u32 type;
101 :
102 0 : if (unformat (input, "t.m.gtp4.dt4 fib-table %u", &fib_index))
103 : {
104 0 : type = SRV6_GTP4_DT4;
105 : }
106 0 : else if (unformat (input, "t.m.gtp4.dt6 fib-table %u local-fib-table %u",
107 : &fib_index, &local_fib_index))
108 : {
109 0 : type = SRV6_GTP4_DT6;
110 : }
111 0 : else if (unformat (input, "t.m.gtp4.dt46 fib-table %u local-fib-table %u",
112 : &fib_index, &local_fib_index))
113 : {
114 0 : type = SRV6_GTP4_DT46;
115 : }
116 : else
117 : {
118 0 : return 0;
119 : }
120 :
121 0 : ls_mem = clib_mem_alloc (sizeof *ls_mem);
122 0 : clib_memset (ls_mem, 0, sizeof *ls_mem);
123 0 : *plugin_mem_p = ls_mem;
124 :
125 0 : ls_mem->fib4_index = fib_table_find (FIB_PROTOCOL_IP4, fib_index);
126 0 : ls_mem->fib6_index = fib_table_find (FIB_PROTOCOL_IP6, fib_index);
127 :
128 0 : if (type == SRV6_GTP4_DT6 || type == SRV6_GTP4_DT46)
129 : {
130 0 : ls_mem->local_fib_index =
131 0 : fib_table_find (FIB_PROTOCOL_IP6, local_fib_index);
132 : }
133 :
134 0 : ls_mem->type = type;
135 :
136 0 : return 1;
137 : }
138 :
139 : static int
140 0 : clb_creation_srv6_t_m_gtp4_dt (ip6_sr_policy_t * sr_policy)
141 : {
142 0 : return 0;
143 : }
144 :
145 : static int
146 0 : clb_removal_srv6_t_m_gtp4_dt (ip6_sr_policy_t * sr_policy)
147 : {
148 : srv6_t_gtp4_dt_param_t *ls_mem;
149 :
150 0 : ls_mem = (srv6_t_gtp4_dt_param_t *) sr_policy->plugin_mem;
151 :
152 0 : clib_mem_free (ls_mem);
153 :
154 0 : return 0;
155 : }
156 :
157 : static clib_error_t *
158 575 : srv6_t_m_gtp4_dt_init (vlib_main_t * vm)
159 : {
160 575 : srv6_t_main_v4_dt_t *sm = &srv6_t_main_v4_dt;
161 : dpo_type_t dpo_type;
162 : vlib_node_t *node;
163 : int rc;
164 :
165 575 : sm->vlib_main = vm;
166 575 : sm->vnet_main = vnet_get_main ();
167 :
168 575 : node = vlib_get_node_by_name (vm, (u8 *) "srv6-t-m-gtp4-dt");
169 575 : sm->t_m_gtp4_dt_node_index = node->index;
170 :
171 575 : node = vlib_get_node_by_name (vm, (u8 *) "error-drop");
172 575 : sm->error_node_index = node->index;
173 :
174 575 : dpo_type = dpo_register_new_type (&dpo_vft, dpo_nodes);
175 :
176 575 : rc = sr_policy_register_function (vm, fn_name, keyword_str, def_str, param_str, 128, //prefix len
177 : &dpo_type,
178 : clb_format_srv6_t_m_gtp4_dt,
179 : clb_unformat_srv6_t_m_gtp4_dt,
180 : clb_creation_srv6_t_m_gtp4_dt,
181 : clb_removal_srv6_t_m_gtp4_dt);
182 575 : if (rc < 0)
183 0 : clib_error_return (0, "SRv6 Transit GTP4.DT Policy function"
184 : "couldn't be registered");
185 575 : return 0;
186 : }
187 :
188 : /* *INDENT-OFF* */
189 14399 : VNET_FEATURE_INIT (srv6_t_m_gtp4_dt, static) =
190 : {
191 : .arc_name = "ip4-unicast",
192 : .node_name = "srv6-t-m-gtp4-dt",
193 : .runs_before = 0,
194 : };
195 :
196 1727 : VLIB_INIT_FUNCTION (srv6_t_m_gtp4_dt_init);
197 : /* *INDENT-ON* */
198 :
199 : /*
200 : * fd.io coding-style-patch-verification: ON
201 : *
202 : * Local Variables:
203 : * eval: (c-set-style "gnu")
204 : * End:
205 : */
|