Line data Source code
1 : /*
2 : * srv6_end_m_gtp6_d_di_di.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_v6_decap_di_t srv6_end_main_v6_decap_di;
25 :
26 : static void
27 0 : clb_dpo_lock_srv6_end_m_gtp6_d_di (dpo_id_t * dpo)
28 : {
29 0 : }
30 :
31 : static void
32 0 : clb_dpo_unlock_srv6_end_m_gtp6_d_di (dpo_id_t * dpo)
33 : {
34 0 : }
35 :
36 : static u8 *
37 0 : clb_dpo_format_srv6_end_m_gtp6_d_di (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_gtp6_d_di,
47 : .dv_unlock = clb_dpo_unlock_srv6_end_m_gtp6_d_di,
48 : .dv_format = clb_dpo_format_srv6_end_m_gtp6_d_di,
49 : };
50 :
51 : const static char *const srv6_end_m_gtp6_d_di_nodes[] = {
52 : "srv6-end-m-gtp6-d-di",
53 : NULL,
54 : };
55 :
56 : const static char *const *const dpo_nodes[DPO_PROTO_NUM] = {
57 : [DPO_PROTO_IP6] = srv6_end_m_gtp6_d_di_nodes,
58 : };
59 :
60 : static u8 fn_name[] = "SRv6-End.M.GTP6.D.DI-plugin";
61 : static u8 keyword_str[] = "end.m.gtp6.d.di";
62 : static u8 def_str[] =
63 : "Endpoint function with drop-in dencapsulation for IPv6/GTP tunnel";
64 : static u8 param_str[] = "<sr-prefix>/<sr-prefixlen> [nhtype <nhtype>]";
65 :
66 : static u8 *
67 0 : clb_format_srv6_end_m_gtp6_d_di (u8 * s, va_list * args)
68 : {
69 0 : srv6_end_gtp6_d_param_t *ls_mem = va_arg (*args, void *);
70 :
71 0 : s = format (s, "SRv6 End gtp6.d Drop-in\n\t");
72 :
73 : s =
74 0 : format (s, "SR Prefix: %U/%d", format_ip6_address, &ls_mem->sr_prefix,
75 : ls_mem->sr_prefixlen);
76 :
77 0 : if (ls_mem->nhtype != SRV6_NHTYPE_NONE)
78 : {
79 0 : if (ls_mem->nhtype == SRV6_NHTYPE_IPV4)
80 0 : s = format (s, ", NHType IPv4\n");
81 0 : else if (ls_mem->nhtype == SRV6_NHTYPE_IPV6)
82 0 : s = format (s, ", NHType IPv6\n");
83 0 : else if (ls_mem->nhtype == SRV6_NHTYPE_NON_IP)
84 0 : s = format (s, ", NHType Non-IP\n");
85 : else
86 0 : s = format (s, ", NHType Unknow(%d)\n", ls_mem->nhtype);
87 : }
88 : else
89 0 : s = format (s, "\n");
90 :
91 0 : return s;
92 : }
93 :
94 : static uword
95 0 : clb_unformat_srv6_end_m_gtp6_d_di (unformat_input_t * input, va_list * args)
96 : {
97 0 : void **plugin_mem_p = va_arg (*args, void **);
98 : srv6_end_gtp6_d_param_t *ls_mem;
99 : ip6_address_t sr_prefix;
100 0 : u32 sr_prefixlen = 0;
101 : u8 nhtype;
102 :
103 0 : if (unformat (input, "end.m.gtp6.d.di %U/%d nhtype ipv4",
104 : unformat_ip6_address, &sr_prefix, &sr_prefixlen))
105 : {
106 0 : nhtype = SRV6_NHTYPE_IPV4;
107 : }
108 0 : else if (unformat (input, "end.m.gtp6.d.di %U/%d nhtype ipv6",
109 : unformat_ip6_address, &sr_prefix, &sr_prefixlen))
110 : {
111 0 : nhtype = SRV6_NHTYPE_IPV6;
112 : }
113 0 : else if (unformat (input, "end.m.gtp6.d.di %U/%d nhtype non-ip",
114 : unformat_ip6_address, &sr_prefix, &sr_prefixlen))
115 : {
116 0 : nhtype = SRV6_NHTYPE_NON_IP;
117 : }
118 0 : else if (unformat (input, "end.m.gtp6.d.di %U/%d",
119 : unformat_ip6_address, &sr_prefix, &sr_prefixlen))
120 : {
121 0 : nhtype = SRV6_NHTYPE_NONE;
122 : }
123 : else
124 : {
125 0 : return 0;
126 : }
127 :
128 0 : ls_mem = clib_mem_alloc (sizeof *ls_mem);
129 0 : clib_memset (ls_mem, 0, sizeof *ls_mem);
130 0 : *plugin_mem_p = ls_mem;
131 :
132 0 : ls_mem->sr_prefix = sr_prefix;
133 0 : ls_mem->sr_prefixlen = sr_prefixlen;
134 0 : ls_mem->nhtype = nhtype;
135 :
136 0 : return 1;
137 : }
138 :
139 : static int
140 0 : clb_creation_srv6_end_m_gtp6_d_di (ip6_sr_localsid_t * localsid)
141 : {
142 0 : return 0;
143 : }
144 :
145 : static int
146 0 : clb_removal_srv6_end_m_gtp6_d_di (ip6_sr_localsid_t * localsid)
147 : {
148 : srv6_end_gtp6_d_param_t *ls_mem;
149 :
150 0 : ls_mem = localsid->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_end_m_gtp6_d_di_init (vlib_main_t * vm)
159 : {
160 575 : srv6_end_main_v6_decap_di_t *sm = &srv6_end_main_v6_decap_di;
161 : ip6srv_combo_header_t *ip6;
162 : dpo_type_t dpo_type;
163 : vlib_node_t *node;
164 : int rc;
165 :
166 575 : sm->vlib_main = vm;
167 575 : sm->vnet_main = vnet_get_main ();
168 :
169 575 : node = vlib_get_node_by_name (vm, (u8 *) "srv6-end-m-gtp6-d-di");
170 575 : sm->end_m_gtp6_d_di_node_index = node->index;
171 :
172 575 : node = vlib_get_node_by_name (vm, (u8 *) "error-drop");
173 575 : sm->error_node_index = node->index;
174 :
175 575 : ip6 = &sm->cache_hdr;
176 :
177 575 : clib_memset_u8 (ip6, 0, sizeof (ip6srv_combo_header_t));
178 :
179 : // IPv6 header (default)
180 575 : ip6->ip.ip_version_traffic_class_and_flow_label = 0x60;
181 575 : ip6->ip.hop_limit = 64;
182 575 : ip6->ip.protocol = IPPROTO_IPV6_ROUTE;
183 :
184 : // SR header (default)
185 575 : ip6->sr.type = 4;
186 :
187 575 : dpo_type = dpo_register_new_type (&dpo_vft, dpo_nodes);
188 :
189 575 : rc = sr_localsid_register_function (vm, fn_name, keyword_str, def_str, param_str, 128, //prefix len
190 : &dpo_type,
191 : clb_format_srv6_end_m_gtp6_d_di,
192 : clb_unformat_srv6_end_m_gtp6_d_di,
193 : clb_creation_srv6_end_m_gtp6_d_di,
194 : clb_removal_srv6_end_m_gtp6_d_di);
195 575 : if (rc < 0)
196 0 : clib_error_return (0, "SRv6 Endpoint GTP6.D.DI LocalSID function"
197 : "couldn't be registered");
198 575 : return 0;
199 : }
200 :
201 : /* *INDENT-OFF* */
202 14399 : VNET_FEATURE_INIT (srv6_end_m_gtp6_d_di, static) =
203 : {
204 : .arc_name = "ip6-unicast",
205 : .node_name = "srv6-end-m-gtp6-d-di",
206 : .runs_before = 0,
207 : };
208 :
209 3455 : VLIB_INIT_FUNCTION (srv6_end_m_gtp6_d_di_init);
210 : /* *INDENT-ON* */
211 :
212 : /*
213 : * fd.io coding-style-patch-verification: ON
214 : *
215 : * Local Variables:
216 : * eval: (c-set-style "gnu")
217 : * End:
218 : */
|