]>
Commit | Line | Data |
---|---|---|
d62a17ae | 1 | /* |
65efcfce LB |
2 | * Copyright 2015-2016, LabN Consulting, L.L.C. |
3 | * | |
4 | * This program is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU General Public License | |
6 | * as published by the Free Software Foundation; either version 2 | |
7 | * of the License, or (at your option) any later version. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | * | |
896014f4 DL |
14 | * You should have received a copy of the GNU General Public License along |
15 | * with this program; see the file COPYING; if not, write to the Free Software | |
16 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
65efcfce LB |
17 | */ |
18 | ||
f8b6f499 | 19 | #include "lib/zebra.h" |
65efcfce | 20 | |
f8b6f499 LB |
21 | #include "lib/memory.h" |
22 | #include "lib/prefix.h" | |
23 | #include "lib/table.h" | |
24 | #include "lib/vty.h" | |
65efcfce | 25 | |
f8b6f499 LB |
26 | #include "bgpd/bgpd.h" |
27 | #include "bgpd/bgp_attr.h" | |
65efcfce | 28 | |
f8b6f499 LB |
29 | #include "bgpd/bgp_encap_types.h" |
30 | #include "bgpd/bgp_encap_tlv.h" | |
65efcfce | 31 | |
f8b6f499 LB |
32 | #include "bgpd/rfapi/rfapi.h" |
33 | #include "bgpd/rfapi/rfapi_encap_tlv.h" | |
34 | #include "bgpd/rfapi/rfapi_private.h" | |
35 | #include "bgpd/rfapi/rfapi_monitor.h" | |
36 | #include "bgpd/rfapi/rfapi_vty.h" | |
37 | #include "bgpd/rfapi/bgp_rfapi_cfg.h" | |
a3b55c25 | 38 | #include "bgpd/rfapi/vnc_debug.h" |
65efcfce | 39 | |
d62a17ae | 40 | static void rfapi_add_endpoint_address_to_subtlv( |
41 | struct bgp *bgp, struct rfapi_ip_addr *ea, | |
42 | struct bgp_tea_subtlv_remote_endpoint *subtlv) | |
65efcfce | 43 | { |
d62a17ae | 44 | subtlv->family = ea->addr_family; |
45 | if (subtlv->family == AF_INET) | |
46 | subtlv->ip_address.v4 = ea->addr.v4; | |
47 | else | |
48 | subtlv->ip_address.v6 = ea->addr.v6; | |
49 | subtlv->as4 = htonl(bgp->as); | |
65efcfce LB |
50 | } |
51 | ||
52 | bgp_encap_types | |
d62a17ae | 53 | rfapi_tunneltype_option_to_tlv(struct bgp *bgp, struct rfapi_ip_addr *ea, |
54 | struct rfapi_tunneltype_option *tto, | |
55 | struct attr *attr, int always_add) | |
65efcfce LB |
56 | { |
57 | ||
d62a17ae | 58 | #define _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ttype) \ |
59 | if ((always_add \ | |
60 | || (bgp->rfapi_cfg \ | |
61 | && !CHECK_FLAG(bgp->rfapi_cfg->flags, \ | |
62 | BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP))) \ | |
63 | && ea \ | |
64 | && !CHECK_SUBTLV_FLAG(&tto->bgpinfo.ttype, \ | |
65 | BGP_TEA_SUBTLV_REMOTE_ENDPOINT)) { \ | |
66 | rfapi_add_endpoint_address_to_subtlv( \ | |
67 | bgp, ea, &tto->bgpinfo.ttype.st_endpoint); \ | |
68 | SET_SUBTLV_FLAG(&tto->bgpinfo.ttype, \ | |
69 | BGP_TEA_SUBTLV_REMOTE_ENDPOINT); \ | |
70 | } | |
71 | ||
72 | struct rfapi_tunneltype_option dto; | |
73 | if (tto == NULL) { /* create default type */ | |
74 | tto = &dto; | |
75 | memset(tto, 0, sizeof(dto)); | |
76 | tto->type = RFAPI_BGP_ENCAP_TYPE_DEFAULT; | |
77 | } | |
78 | switch (tto->type) { | |
79 | case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: | |
80 | _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(l2tpv3_ip); | |
81 | bgp_encap_type_l2tpv3overip_to_tlv(&tto->bgpinfo.l2tpv3_ip, | |
82 | attr); | |
83 | break; | |
84 | ||
85 | case BGP_ENCAP_TYPE_GRE: | |
86 | _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(gre); | |
87 | bgp_encap_type_gre_to_tlv(&tto->bgpinfo.gre, attr); | |
88 | break; | |
89 | ||
90 | case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: | |
91 | _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(transmit_tunnel_endpoint); | |
92 | bgp_encap_type_transmit_tunnel_endpoint( | |
93 | &tto->bgpinfo.transmit_tunnel_endpoint, attr); | |
94 | break; | |
95 | ||
96 | case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: | |
97 | _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ipsec_tunnel); | |
98 | bgp_encap_type_ipsec_in_tunnel_mode_to_tlv( | |
99 | &tto->bgpinfo.ipsec_tunnel, attr); | |
100 | break; | |
101 | ||
102 | case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: | |
103 | _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ip_ipsec); | |
104 | bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv( | |
105 | &tto->bgpinfo.ip_ipsec, attr); | |
106 | break; | |
107 | ||
108 | case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: | |
109 | _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_ipsec); | |
110 | bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv( | |
111 | &tto->bgpinfo.mpls_ipsec, attr); | |
112 | break; | |
113 | ||
114 | case BGP_ENCAP_TYPE_IP_IN_IP: | |
115 | _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ip_ip); | |
116 | bgp_encap_type_ip_in_ip_to_tlv(&tto->bgpinfo.ip_ip, attr); | |
117 | break; | |
118 | ||
119 | case BGP_ENCAP_TYPE_VXLAN: | |
120 | _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(vxlan); | |
121 | bgp_encap_type_vxlan_to_tlv(&tto->bgpinfo.vxlan, attr); | |
122 | break; | |
123 | ||
124 | case BGP_ENCAP_TYPE_NVGRE: | |
125 | _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(nvgre); | |
126 | bgp_encap_type_nvgre_to_tlv(&tto->bgpinfo.nvgre, attr); | |
127 | break; | |
128 | ||
129 | case BGP_ENCAP_TYPE_MPLS: | |
130 | /* nothing to do for MPLS */ | |
131 | break; | |
132 | ||
133 | case BGP_ENCAP_TYPE_MPLS_IN_GRE: | |
134 | _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_gre); | |
135 | bgp_encap_type_mpls_in_gre_to_tlv(&tto->bgpinfo.mpls_gre, attr); | |
136 | break; | |
137 | ||
138 | case BGP_ENCAP_TYPE_VXLAN_GPE: | |
139 | _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(vxlan_gpe); | |
140 | bgp_encap_type_vxlan_gpe_to_tlv(&tto->bgpinfo.vxlan_gpe, attr); | |
141 | break; | |
142 | ||
143 | case BGP_ENCAP_TYPE_MPLS_IN_UDP: | |
144 | _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_udp); | |
145 | bgp_encap_type_mpls_in_udp_to_tlv(&tto->bgpinfo.mpls_udp, attr); | |
146 | break; | |
147 | ||
148 | case BGP_ENCAP_TYPE_PBB: | |
149 | _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(pbb); | |
150 | bgp_encap_type_pbb_to_tlv(&tto->bgpinfo.pbb, attr); | |
151 | break; | |
152 | ||
153 | default: | |
154 | assert(0); | |
155 | } | |
156 | return tto->type; | |
65efcfce LB |
157 | } |
158 | ||
d62a17ae | 159 | struct rfapi_un_option *rfapi_encap_tlv_to_un_option(struct attr *attr) |
65efcfce | 160 | { |
d62a17ae | 161 | struct rfapi_un_option *uo = NULL; |
162 | struct rfapi_tunneltype_option *tto; | |
163 | int rc; | |
164 | struct bgp_attr_encap_subtlv *stlv; | |
165 | ||
166 | /* no tunnel encap attr stored */ | |
167 | if (!attr->encap_tunneltype) | |
168 | return NULL; | |
169 | ||
170 | stlv = attr->encap_subtlvs; | |
171 | ||
172 | uo = XCALLOC(MTYPE_RFAPI_UN_OPTION, sizeof(struct rfapi_un_option)); | |
173 | assert(uo); | |
174 | uo->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE; | |
175 | uo->v.tunnel.type = attr->encap_tunneltype; | |
176 | tto = &uo->v.tunnel; | |
177 | ||
178 | switch (attr->encap_tunneltype) { | |
179 | case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: | |
180 | rc = tlv_to_bgp_encap_type_l2tpv3overip( | |
181 | stlv, &tto->bgpinfo.l2tpv3_ip); | |
182 | break; | |
183 | ||
184 | case BGP_ENCAP_TYPE_GRE: | |
185 | rc = tlv_to_bgp_encap_type_gre(stlv, &tto->bgpinfo.gre); | |
186 | break; | |
187 | ||
188 | case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: | |
189 | rc = tlv_to_bgp_encap_type_transmit_tunnel_endpoint( | |
190 | stlv, &tto->bgpinfo.transmit_tunnel_endpoint); | |
191 | break; | |
192 | ||
193 | case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: | |
194 | rc = tlv_to_bgp_encap_type_ipsec_in_tunnel_mode( | |
195 | stlv, &tto->bgpinfo.ipsec_tunnel); | |
196 | break; | |
197 | ||
198 | case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: | |
199 | rc = tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode( | |
200 | stlv, &tto->bgpinfo.ip_ipsec); | |
201 | break; | |
202 | ||
203 | case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: | |
204 | rc = tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode( | |
205 | stlv, &tto->bgpinfo.mpls_ipsec); | |
206 | break; | |
207 | ||
208 | case BGP_ENCAP_TYPE_IP_IN_IP: | |
209 | rc = tlv_to_bgp_encap_type_ip_in_ip(stlv, &tto->bgpinfo.ip_ip); | |
210 | break; | |
211 | ||
212 | case BGP_ENCAP_TYPE_VXLAN: | |
213 | rc = tlv_to_bgp_encap_type_vxlan(stlv, &tto->bgpinfo.vxlan); | |
214 | break; | |
215 | ||
216 | case BGP_ENCAP_TYPE_NVGRE: | |
217 | rc = tlv_to_bgp_encap_type_nvgre(stlv, &tto->bgpinfo.nvgre); | |
218 | break; | |
219 | ||
220 | case BGP_ENCAP_TYPE_MPLS: | |
221 | rc = tlv_to_bgp_encap_type_mpls(stlv, &tto->bgpinfo.mpls); | |
222 | break; | |
223 | ||
224 | case BGP_ENCAP_TYPE_MPLS_IN_GRE: | |
225 | rc = tlv_to_bgp_encap_type_mpls_in_gre(stlv, | |
226 | &tto->bgpinfo.mpls_gre); | |
227 | break; | |
228 | ||
229 | case BGP_ENCAP_TYPE_VXLAN_GPE: | |
230 | rc = tlv_to_bgp_encap_type_vxlan_gpe(stlv, | |
231 | &tto->bgpinfo.vxlan_gpe); | |
232 | break; | |
233 | ||
234 | case BGP_ENCAP_TYPE_MPLS_IN_UDP: | |
235 | rc = tlv_to_bgp_encap_type_mpls_in_udp(stlv, | |
236 | &tto->bgpinfo.mpls_udp); | |
237 | break; | |
238 | ||
239 | case BGP_ENCAP_TYPE_PBB: | |
240 | rc = tlv_to_bgp_encap_type_pbb(stlv, &tto->bgpinfo.pbb); | |
241 | break; | |
242 | ||
243 | default: | |
244 | vnc_zlog_debug_verbose("%s: unknown tunnel type %d", __func__, | |
245 | attr->encap_tunneltype); | |
246 | rc = -1; | |
247 | break; | |
248 | } | |
249 | if (rc) { | |
250 | XFREE(MTYPE_RFAPI_UN_OPTION, uo); | |
251 | uo = NULL; | |
252 | } | |
253 | return uo; | |
65efcfce LB |
254 | } |
255 | ||
256 | /*********************************************************************** | |
257 | * SUBTLV PRINT | |
258 | ***********************************************************************/ | |
259 | ||
d62a17ae | 260 | static void subtlv_print_encap_l2tpv3_over_ip( |
261 | void *stream, int column_offset, | |
262 | struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st) | |
65efcfce | 263 | { |
d62a17ae | 264 | int (*fp)(void *, const char *, ...); |
265 | struct vty *vty; | |
266 | void *out; | |
267 | const char *vty_newline; | |
268 | ||
269 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) | |
270 | return; | |
271 | if (!st) | |
272 | return; | |
273 | ||
274 | fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(L2TPv3 over IP)", | |
275 | vty_newline); | |
276 | fp(out, "%*s SessionID: %d%s", column_offset, "", st->sessionid, | |
277 | vty_newline); | |
278 | fp(out, "%*s Cookie: (length %d)%s", column_offset, "", | |
279 | st->cookie_length, vty_newline); | |
65efcfce LB |
280 | } |
281 | ||
d62a17ae | 282 | static void subtlv_print_encap_gre(void *stream, int column_offset, |
283 | struct bgp_tea_subtlv_encap_gre_key *st) | |
65efcfce | 284 | { |
d62a17ae | 285 | int (*fp)(void *, const char *, ...); |
286 | struct vty *vty; | |
287 | void *out; | |
288 | const char *vty_newline; | |
289 | ||
290 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) | |
291 | return; | |
292 | if (!st) | |
293 | return; | |
294 | ||
295 | fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(GRE)", | |
296 | vty_newline); | |
297 | fp(out, "%*s GRE key: %d (0x%x)%s", column_offset, "", st->gre_key, | |
298 | st->gre_key, vty_newline); | |
65efcfce LB |
299 | } |
300 | ||
d62a17ae | 301 | static void subtlv_print_encap_pbb(void *stream, int column_offset, |
302 | struct bgp_tea_subtlv_encap_pbb *st) | |
65efcfce | 303 | { |
d62a17ae | 304 | int (*fp)(void *, const char *, ...); |
305 | struct vty *vty; | |
306 | void *out; | |
307 | const char *vty_newline; | |
308 | ||
309 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) | |
310 | return; | |
311 | if (!st) | |
312 | return; | |
313 | ||
314 | fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(PBB)", | |
315 | vty_newline); | |
316 | if (st->flag_isid) { | |
317 | fp(out, "%*s ISID: %d (0x%x)%s", column_offset, "", st->isid, | |
318 | st->isid, vty_newline); | |
319 | } | |
320 | if (st->flag_vid) { | |
321 | fp(out, "%*s VID: %d (0x%x)%s", column_offset, "", st->vid, | |
322 | st->vid, vty_newline); | |
323 | } | |
324 | fp(out, "%*s MACADDR %02x:%02x:%02x:%02x:%02x:%02x%s", column_offset, | |
325 | "", st->macaddr[0], st->macaddr[1], st->macaddr[2], st->macaddr[3], | |
326 | st->macaddr[4], st->macaddr[5], vty_newline); | |
65efcfce LB |
327 | } |
328 | ||
d62a17ae | 329 | static void subtlv_print_proto_type(void *stream, int column_offset, |
330 | struct bgp_tea_subtlv_proto_type *st) | |
65efcfce | 331 | { |
d62a17ae | 332 | int (*fp)(void *, const char *, ...); |
333 | struct vty *vty; | |
334 | void *out; | |
335 | const char *vty_newline; | |
336 | ||
337 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) | |
338 | return; | |
339 | if (!st) | |
340 | return; | |
341 | ||
342 | fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(Proto Type)", | |
343 | vty_newline); | |
344 | fp(out, "%*s Proto %d (0x%x)%s", column_offset, "", st->proto, | |
345 | st->proto, vty_newline); | |
65efcfce LB |
346 | } |
347 | ||
d62a17ae | 348 | static void subtlv_print_color(void *stream, int column_offset, |
349 | struct bgp_tea_subtlv_color *st) | |
65efcfce | 350 | { |
d62a17ae | 351 | int (*fp)(void *, const char *, ...); |
352 | struct vty *vty; | |
353 | void *out; | |
354 | const char *vty_newline; | |
355 | ||
356 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) | |
357 | return; | |
358 | if (!st) | |
359 | return; | |
360 | ||
361 | fp(out, "%*s%s%s", column_offset, "", "SubTLV: Color", vty_newline); | |
362 | fp(out, "%*s Color: %d (0x%x)", column_offset, "", st->color, | |
363 | st->color, vty_newline); | |
65efcfce LB |
364 | } |
365 | ||
d62a17ae | 366 | static void subtlv_print_ipsec_ta(void *stream, int column_offset, |
367 | struct bgp_tea_subtlv_ipsec_ta *st) | |
65efcfce | 368 | { |
d62a17ae | 369 | int (*fp)(void *, const char *, ...); |
370 | struct vty *vty; | |
371 | void *out; | |
372 | const char *vty_newline; | |
373 | ||
374 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) | |
375 | return; | |
376 | if (!st) | |
377 | return; | |
378 | ||
379 | fp(out, "%*s%s%s", column_offset, "", "SubTLV: IPSEC TA", vty_newline); | |
380 | fp(out, "%*s Authenticator Type: %d (0x%x)", column_offset, "", | |
381 | st->authenticator_type, st->authenticator_type, vty_newline); | |
382 | fp(out, "%*s Authenticator: (length %d)", column_offset, "", | |
383 | st->authenticator_length, vty_newline); | |
65efcfce LB |
384 | } |
385 | ||
386 | /*********************************************************************** | |
387 | * TLV PRINT | |
388 | ***********************************************************************/ | |
389 | ||
390 | static void | |
d62a17ae | 391 | print_encap_type_l2tpv3overip(void *stream, int column_offset, |
392 | struct bgp_encap_type_l2tpv3_over_ip *bet) | |
65efcfce | 393 | { |
d62a17ae | 394 | const char *type = "L2TPv3 over IP"; |
395 | int (*fp)(void *, const char *, ...); | |
396 | struct vty *vty; | |
397 | void *out; | |
398 | const char *vty_newline; | |
399 | ||
400 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) | |
401 | return; | |
402 | if (!bet) | |
403 | return; | |
404 | ||
405 | fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); | |
406 | ||
407 | subtlv_print_encap_l2tpv3_over_ip(stream, column_offset + 2, | |
408 | &bet->st_encap); | |
409 | subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto); | |
410 | subtlv_print_color(stream, column_offset + 2, &bet->st_color); | |
65efcfce LB |
411 | } |
412 | ||
d62a17ae | 413 | static void print_encap_type_gre(void *stream, int column_offset, |
414 | struct bgp_encap_type_gre *bet) | |
65efcfce | 415 | { |
d62a17ae | 416 | const char *type = "GRE"; |
417 | int (*fp)(void *, const char *, ...); | |
418 | struct vty *vty; | |
419 | void *out; | |
420 | const char *vty_newline; | |
421 | ||
422 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) | |
423 | return; | |
424 | if (!bet) | |
425 | return; | |
426 | ||
427 | fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); | |
428 | ||
429 | subtlv_print_encap_gre(stream, column_offset + 2, &bet->st_encap); | |
430 | subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto); | |
431 | subtlv_print_color(stream, column_offset + 2, &bet->st_color); | |
65efcfce LB |
432 | } |
433 | ||
d62a17ae | 434 | static void print_encap_type_ip_in_ip(void *stream, int column_offset, |
435 | struct bgp_encap_type_ip_in_ip *bet) | |
65efcfce | 436 | { |
d62a17ae | 437 | const char *type = "IP in IP"; |
438 | int (*fp)(void *, const char *, ...); | |
439 | struct vty *vty; | |
440 | void *out; | |
441 | const char *vty_newline; | |
65efcfce | 442 | |
d62a17ae | 443 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) |
444 | return; | |
445 | if (!bet) | |
446 | return; | |
65efcfce | 447 | |
d62a17ae | 448 | fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); |
65efcfce | 449 | |
d62a17ae | 450 | subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto); |
451 | subtlv_print_color(stream, column_offset + 2, &bet->st_color); | |
65efcfce LB |
452 | } |
453 | ||
d62a17ae | 454 | static void print_encap_type_transmit_tunnel_endpoint( |
455 | void *stream, int column_offset, | |
456 | struct bgp_encap_type_transmit_tunnel_endpoint *bet) | |
65efcfce | 457 | { |
d62a17ae | 458 | const char *type = "Transmit Tunnel Endpoint"; |
459 | int (*fp)(void *, const char *, ...); | |
460 | struct vty *vty; | |
461 | void *out; | |
462 | const char *vty_newline; | |
65efcfce | 463 | |
d62a17ae | 464 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) |
465 | return; | |
466 | if (!bet) | |
467 | return; | |
65efcfce | 468 | |
d62a17ae | 469 | fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); |
65efcfce | 470 | |
d62a17ae | 471 | /* no subtlvs for this type */ |
65efcfce LB |
472 | } |
473 | ||
d62a17ae | 474 | static void print_encap_type_ipsec_in_tunnel_mode( |
475 | void *stream, int column_offset, | |
476 | struct bgp_encap_type_ipsec_in_tunnel_mode *bet) | |
65efcfce | 477 | { |
d62a17ae | 478 | const char *type = "IPSEC in Tunnel mode"; |
479 | int (*fp)(void *, const char *, ...); | |
480 | struct vty *vty; | |
481 | void *out; | |
482 | const char *vty_newline; | |
483 | ||
484 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) | |
485 | return; | |
486 | if (!bet) | |
487 | return; | |
488 | ||
489 | fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); | |
490 | subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta); | |
65efcfce LB |
491 | } |
492 | ||
d62a17ae | 493 | static void print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode( |
494 | void *stream, int column_offset, | |
495 | struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet) | |
65efcfce | 496 | { |
d62a17ae | 497 | const char *type = "IP in IP Tunnel with IPSEC transport mode"; |
498 | int (*fp)(void *, const char *, ...); | |
499 | struct vty *vty; | |
500 | void *out; | |
501 | const char *vty_newline; | |
65efcfce | 502 | |
d62a17ae | 503 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) |
504 | return; | |
505 | if (!bet) | |
506 | return; | |
65efcfce | 507 | |
d62a17ae | 508 | fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); |
65efcfce | 509 | |
d62a17ae | 510 | subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta); |
65efcfce LB |
511 | } |
512 | ||
d62a17ae | 513 | static void print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode( |
514 | void *stream, int column_offset, | |
515 | struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet) | |
65efcfce | 516 | { |
d62a17ae | 517 | const char *type = "MPLS in IP Tunnel with IPSEC transport mode"; |
518 | int (*fp)(void *, const char *, ...); | |
519 | struct vty *vty; | |
520 | void *out; | |
521 | const char *vty_newline; | |
65efcfce | 522 | |
d62a17ae | 523 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) |
524 | return; | |
525 | if (!bet) | |
526 | return; | |
65efcfce | 527 | |
d62a17ae | 528 | fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); |
65efcfce | 529 | |
d62a17ae | 530 | subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta); |
65efcfce LB |
531 | } |
532 | ||
533 | ||
d62a17ae | 534 | static void print_encap_type_pbb(void *stream, int column_offset, |
535 | struct bgp_encap_type_pbb *bet) | |
65efcfce | 536 | { |
d62a17ae | 537 | const char *type = "PBB"; |
538 | int (*fp)(void *, const char *, ...); | |
539 | struct vty *vty; | |
540 | void *out; | |
541 | const char *vty_newline; | |
65efcfce | 542 | |
d62a17ae | 543 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) |
544 | return; | |
545 | if (!bet) | |
546 | return; | |
65efcfce | 547 | |
d62a17ae | 548 | fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); |
65efcfce | 549 | |
d62a17ae | 550 | subtlv_print_encap_pbb(stream, column_offset + 2, &bet->st_encap); |
65efcfce LB |
551 | } |
552 | ||
553 | ||
d62a17ae | 554 | static void print_encap_type_vxlan(void *stream, int column_offset, |
555 | struct bgp_encap_type_vxlan *bet) | |
65efcfce | 556 | { |
d62a17ae | 557 | const char *type = "VXLAN"; |
558 | int (*fp)(void *, const char *, ...); | |
559 | struct vty *vty; | |
560 | void *out; | |
561 | const char *vty_newline; | |
65efcfce | 562 | |
d62a17ae | 563 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) |
564 | return; | |
565 | if (!bet) | |
566 | return; | |
65efcfce | 567 | |
d62a17ae | 568 | fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); |
65efcfce | 569 | |
d62a17ae | 570 | /* no subtlvs for this type */ |
65efcfce LB |
571 | } |
572 | ||
573 | ||
d62a17ae | 574 | static void print_encap_type_nvgre(void *stream, int column_offset, |
575 | struct bgp_encap_type_nvgre *bet) | |
65efcfce | 576 | { |
d62a17ae | 577 | const char *type = "NVGRE"; |
578 | int (*fp)(void *, const char *, ...); | |
579 | struct vty *vty; | |
580 | void *out; | |
581 | const char *vty_newline; | |
65efcfce | 582 | |
d62a17ae | 583 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) |
584 | return; | |
585 | if (!bet) | |
586 | return; | |
65efcfce | 587 | |
d62a17ae | 588 | fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); |
65efcfce | 589 | |
d62a17ae | 590 | /* no subtlvs for this type */ |
65efcfce LB |
591 | } |
592 | ||
d62a17ae | 593 | static void print_encap_type_mpls(void *stream, int column_offset, |
594 | struct bgp_encap_type_mpls *bet) | |
65efcfce | 595 | { |
d62a17ae | 596 | const char *type = "MPLS"; |
597 | int (*fp)(void *, const char *, ...); | |
598 | struct vty *vty; | |
599 | void *out; | |
600 | const char *vty_newline; | |
65efcfce | 601 | |
d62a17ae | 602 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) |
603 | return; | |
604 | if (!bet) | |
605 | return; | |
65efcfce | 606 | |
d62a17ae | 607 | fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); |
65efcfce | 608 | |
d62a17ae | 609 | /* no subtlvs for this type */ |
65efcfce LB |
610 | } |
611 | ||
d62a17ae | 612 | static void print_encap_type_mpls_in_gre(void *stream, int column_offset, |
613 | struct bgp_encap_type_mpls_in_gre *bet) | |
65efcfce | 614 | { |
d62a17ae | 615 | const char *type = "MPLS in GRE"; |
616 | int (*fp)(void *, const char *, ...); | |
617 | struct vty *vty; | |
618 | void *out; | |
619 | const char *vty_newline; | |
65efcfce | 620 | |
d62a17ae | 621 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) |
622 | return; | |
623 | if (!bet) | |
624 | return; | |
65efcfce | 625 | |
d62a17ae | 626 | fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); |
65efcfce | 627 | |
d62a17ae | 628 | /* no subtlvs for this type */ |
65efcfce LB |
629 | } |
630 | ||
d62a17ae | 631 | static void print_encap_type_vxlan_gpe(void *stream, int column_offset, |
632 | struct bgp_encap_type_vxlan_gpe *bet) | |
65efcfce | 633 | { |
d62a17ae | 634 | const char *type = "VXLAN GPE"; |
635 | int (*fp)(void *, const char *, ...); | |
636 | struct vty *vty; | |
637 | void *out; | |
638 | const char *vty_newline; | |
65efcfce | 639 | |
d62a17ae | 640 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) |
641 | return; | |
642 | if (!bet) | |
643 | return; | |
65efcfce | 644 | |
d62a17ae | 645 | fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); |
65efcfce | 646 | |
d62a17ae | 647 | /* no subtlvs for this type */ |
65efcfce LB |
648 | } |
649 | ||
d62a17ae | 650 | static void print_encap_type_mpls_in_udp(void *stream, int column_offset, |
651 | struct bgp_encap_type_mpls_in_udp *bet) | |
65efcfce | 652 | { |
d62a17ae | 653 | const char *type = "MPLS in UDP"; |
654 | int (*fp)(void *, const char *, ...); | |
655 | struct vty *vty; | |
656 | void *out; | |
657 | const char *vty_newline; | |
65efcfce | 658 | |
d62a17ae | 659 | if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) |
660 | return; | |
661 | if (!bet) | |
662 | return; | |
65efcfce | 663 | |
d62a17ae | 664 | fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); |
65efcfce | 665 | |
d62a17ae | 666 | /* no subtlvs for this type */ |
65efcfce LB |
667 | } |
668 | ||
d62a17ae | 669 | void rfapi_print_tunneltype_option(void *stream, int column_offset, |
670 | struct rfapi_tunneltype_option *tto) | |
65efcfce | 671 | { |
d62a17ae | 672 | switch (tto->type) { |
673 | case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: | |
674 | print_encap_type_l2tpv3overip(stream, column_offset, | |
675 | &tto->bgpinfo.l2tpv3_ip); | |
676 | break; | |
677 | ||
678 | case BGP_ENCAP_TYPE_GRE: | |
679 | print_encap_type_gre(stream, column_offset, &tto->bgpinfo.gre); | |
680 | break; | |
681 | ||
682 | case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: | |
683 | print_encap_type_transmit_tunnel_endpoint( | |
684 | stream, column_offset, | |
685 | &tto->bgpinfo.transmit_tunnel_endpoint); | |
686 | break; | |
687 | ||
688 | case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: | |
689 | print_encap_type_ipsec_in_tunnel_mode( | |
690 | stream, column_offset, &tto->bgpinfo.ipsec_tunnel); | |
691 | break; | |
692 | ||
693 | case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: | |
694 | print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode( | |
695 | stream, column_offset, &tto->bgpinfo.ip_ipsec); | |
696 | break; | |
697 | ||
698 | case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: | |
699 | print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode( | |
700 | stream, column_offset, &tto->bgpinfo.mpls_ipsec); | |
701 | break; | |
702 | ||
703 | case BGP_ENCAP_TYPE_IP_IN_IP: | |
704 | print_encap_type_ip_in_ip(stream, column_offset, | |
705 | &tto->bgpinfo.ip_ip); | |
706 | break; | |
707 | ||
708 | case BGP_ENCAP_TYPE_VXLAN: | |
709 | print_encap_type_vxlan(stream, column_offset, | |
710 | &tto->bgpinfo.vxlan); | |
711 | break; | |
712 | ||
713 | case BGP_ENCAP_TYPE_NVGRE: | |
714 | print_encap_type_nvgre(stream, column_offset, | |
715 | &tto->bgpinfo.nvgre); | |
716 | break; | |
717 | ||
718 | case BGP_ENCAP_TYPE_MPLS: | |
719 | print_encap_type_mpls(stream, column_offset, | |
720 | &tto->bgpinfo.mpls); | |
721 | break; | |
722 | ||
723 | case BGP_ENCAP_TYPE_MPLS_IN_GRE: | |
724 | print_encap_type_mpls_in_gre(stream, column_offset, | |
725 | &tto->bgpinfo.mpls_gre); | |
726 | break; | |
727 | ||
728 | case BGP_ENCAP_TYPE_VXLAN_GPE: | |
729 | print_encap_type_vxlan_gpe(stream, column_offset, | |
730 | &tto->bgpinfo.vxlan_gpe); | |
731 | break; | |
732 | ||
733 | case BGP_ENCAP_TYPE_MPLS_IN_UDP: | |
734 | print_encap_type_mpls_in_udp(stream, column_offset, | |
735 | &tto->bgpinfo.mpls_udp); | |
736 | break; | |
737 | ||
738 | case BGP_ENCAP_TYPE_PBB: | |
739 | print_encap_type_pbb(stream, column_offset, &tto->bgpinfo.pbb); | |
740 | break; | |
741 | ||
742 | default: | |
743 | assert(0); | |
744 | } | |
65efcfce | 745 | } |