]>
Commit | Line | Data |
---|---|---|
587ff0fd LB |
1 | |
2 | /* | |
3 | * This file created by LabN Consulting, L.L.C. | |
4 | * | |
5 | * | |
6 | * This file is based on bgp_mplsvpn.c which is Copyright (C) 2000 | |
7 | * Kunihiro Ishiguro <kunihiro@zebra.org> | |
8 | * | |
9 | */ | |
10 | ||
11 | /* | |
12 | ||
13 | This file is part of GNU Zebra. | |
14 | ||
15 | GNU Zebra is free software; you can redistribute it and/or modify it | |
16 | under the terms of the GNU General Public License as published by the | |
17 | Free Software Foundation; either version 2, or (at your option) any | |
18 | later version. | |
19 | ||
20 | GNU Zebra is distributed in the hope that it will be useful, but | |
21 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
22 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
23 | General Public License for more details. | |
24 | ||
25 | You should have received a copy of the GNU General Public License | |
26 | along with GNU Zebra; see the file COPYING. If not, write to the Free | |
27 | Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
28 | 02111-1307, USA. */ | |
29 | ||
30 | #include <zebra.h> | |
31 | ||
32 | #include "command.h" | |
33 | #include "prefix.h" | |
34 | #include "log.h" | |
35 | #include "memory.h" | |
36 | #include "stream.h" | |
37 | #include "filter.h" | |
38 | ||
39 | #include "bgpd/bgpd.h" | |
40 | #include "bgpd/bgp_table.h" | |
41 | #include "bgpd/bgp_route.h" | |
42 | #include "bgpd/bgp_attr.h" | |
43 | #include "bgpd/bgp_ecommunity.h" | |
44 | #include "bgpd/bgp_mplsvpn.h" | |
45 | #include "bgpd/bgp_vty.h" | |
46 | #include "bgpd/bgp_encap.h" | |
47 | ||
65efcfce | 48 | #if ENABLE_BGP_VNC |
f8b6f499 | 49 | #include "bgpd/rfapi/rfapi_backend.h" |
65efcfce | 50 | #endif |
587ff0fd LB |
51 | |
52 | static void | |
53 | ecom2prd(struct ecommunity *ecom, struct prefix_rd *prd) | |
54 | { | |
55 | int i; | |
56 | ||
57 | memset(prd, 0, sizeof(struct prefix_rd)); | |
58 | prd->family = AF_UNSPEC; | |
59 | prd->prefixlen = 64; | |
60 | ||
61 | if (!ecom) | |
62 | return; | |
63 | ||
64 | for (i = 0; i < (ecom->size * ECOMMUNITY_SIZE); i += ECOMMUNITY_SIZE) { | |
65 | ||
66 | uint8_t *ep; | |
67 | ||
68 | ep = ecom->val + i; | |
69 | ||
70 | switch (ep[0]) { | |
71 | default: | |
72 | continue; | |
73 | ||
74 | case 0x80: | |
75 | case 0x81: | |
76 | case 0x82: | |
77 | if (ep[1] == 0x0) { | |
78 | prd->val[1] = ep[0] & 0x03; | |
79 | memcpy(prd->val + 2, ep + 2, 6); | |
80 | return; | |
81 | } | |
82 | } | |
83 | } | |
84 | } | |
85 | ||
86 | int | |
87 | bgp_nlri_parse_encap( | |
587ff0fd | 88 | struct peer *peer, |
423a9d64 PJ |
89 | struct attr *attr, |
90 | struct bgp_nlri *packet) | |
587ff0fd LB |
91 | { |
92 | u_char *pnt; | |
93 | u_char *lim; | |
423a9d64 | 94 | afi_t afi = packet->afi; |
587ff0fd LB |
95 | struct prefix p; |
96 | int psize = 0; | |
97 | int prefixlen; | |
98 | struct rd_as rd_as; | |
99 | struct rd_ip rd_ip; | |
100 | struct prefix_rd prd; | |
101 | struct ecommunity *pEcom = NULL; | |
102 | u_int16_t rdtype = 0xffff; | |
103 | char buf[BUFSIZ]; | |
104 | ||
105 | /* Check peer status. */ | |
106 | if (peer->status != Established) | |
107 | return 0; | |
108 | ||
109 | /* Make prefix_rd */ | |
110 | if (attr && attr->extra && attr->extra->ecommunity) | |
111 | pEcom = attr->extra->ecommunity; | |
112 | ||
113 | ecom2prd(pEcom, &prd); | |
114 | memset(&rd_as, 0, sizeof(rd_as)); | |
115 | memset(&rd_ip, 0, sizeof(rd_ip)); | |
116 | ||
117 | if (pEcom) { | |
118 | ||
119 | rdtype = (prd.val[0] << 8) | prd.val[1]; | |
120 | ||
121 | /* Decode RD value. */ | |
122 | if (rdtype == RD_TYPE_AS) | |
123 | decode_rd_as (prd.val + 2, &rd_as); | |
124 | else if (rdtype == RD_TYPE_IP) | |
125 | decode_rd_ip (prd.val + 2, &rd_ip); | |
126 | else if (rdtype == RD_TYPE_AS4) | |
127 | decode_rd_as4 (prd.val + 2, &rd_as); | |
128 | else | |
129 | { | |
130 | zlog_err ("Invalid RD type %d", rdtype); | |
131 | } | |
132 | ||
133 | } | |
134 | ||
135 | /* | |
136 | * NB: this code was based on the MPLS VPN code, which supported RDs. | |
137 | * For the moment we are retaining the underlying RIB structure that | |
138 | * keeps a per-RD radix tree, but since the RDs are not carried over | |
139 | * the wire, we set the RD internally to 0. | |
140 | */ | |
141 | prd.family = AF_UNSPEC; | |
142 | prd.prefixlen = 64; | |
143 | memset(prd.val, 0, sizeof(prd.val)); | |
144 | ||
145 | pnt = packet->nlri; | |
146 | lim = pnt + packet->length; | |
147 | ||
148 | for (; pnt < lim; pnt += psize) | |
149 | { | |
150 | /* Clear prefix structure. */ | |
151 | memset (&p, 0, sizeof (struct prefix)); | |
152 | ||
153 | /* Fetch prefix length. */ | |
154 | prefixlen = *pnt++; | |
155 | p.family = afi2family(afi); | |
156 | if (p.family == 0) { | |
157 | /* bad afi, shouldn't happen */ | |
158 | zlog_warn("%s: bad afi %d, dropping incoming route", __func__, afi); | |
159 | continue; | |
160 | } | |
161 | psize = PSIZE (prefixlen); | |
162 | ||
163 | p.prefixlen = prefixlen; | |
164 | memcpy (&p.u.prefix, pnt, psize); | |
165 | ||
166 | if (pnt + psize > lim) | |
167 | return -1; | |
168 | ||
169 | ||
170 | if (rdtype == RD_TYPE_AS) | |
171 | zlog_info ("rd-as %u:%u prefix %s/%d", rd_as.as, rd_as.val, | |
172 | inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ), | |
173 | p.prefixlen); | |
174 | else if (rdtype == RD_TYPE_IP) | |
175 | zlog_info ("rd-ip %s:%u prefix %s/%d", inet_ntoa (rd_ip.ip), | |
176 | rd_ip.val, | |
177 | inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ), | |
178 | p.prefixlen); | |
179 | else if (rdtype == RD_TYPE_AS4) | |
180 | zlog_info ("rd-as4 %u:%u prefix %s/%d", rd_as.as, rd_as.val, | |
181 | inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ), | |
182 | p.prefixlen); | |
183 | else | |
184 | zlog_info ("rd unknown, default to 0:0 prefix %s/%d", | |
185 | inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ), | |
186 | p.prefixlen); | |
187 | ||
423a9d64 | 188 | if (attr) { |
587ff0fd LB |
189 | bgp_update (peer, &p, 0, attr, afi, SAFI_ENCAP, |
190 | ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0); | |
65efcfce LB |
191 | #if ENABLE_BGP_VNC |
192 | rfapiProcessUpdate(peer, NULL, &p, &prd, attr, afi, SAFI_ENCAP, | |
193 | ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL); | |
194 | #endif | |
587ff0fd | 195 | } else { |
65efcfce LB |
196 | #if ENABLE_BGP_VNC |
197 | rfapiProcessWithdraw(peer, NULL, &p, &prd, attr, afi, SAFI_ENCAP, | |
198 | ZEBRA_ROUTE_BGP, 0); | |
199 | #endif | |
587ff0fd LB |
200 | bgp_withdraw (peer, &p, 0, attr, afi, SAFI_ENCAP, |
201 | ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL); | |
202 | } | |
203 | } | |
204 | ||
205 | /* Packet length consistency check. */ | |
206 | if (pnt != lim) | |
207 | return -1; | |
208 | ||
209 | return 0; | |
210 | } | |
211 | ||
212 | ||
213 | /* TBD: these routes should probably all be host routes */ | |
214 | ||
215 | /* For testing purpose, static route of ENCAP. */ | |
216 | DEFUN (encap_network, | |
217 | encap_network_cmd, | |
218 | "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD", | |
219 | "Specify a network to announce via BGP\n" | |
0c7b1b01 | 220 | "IPv4 prefix\n" |
587ff0fd LB |
221 | "Specify Route Distinguisher\n" |
222 | "ENCAP Route Distinguisher\n" | |
223 | "BGP tag\n" | |
224 | "tag value\n") | |
225 | { | |
5bf15956 DW |
226 | int idx_ipv4 = 1; |
227 | int idx_rd = 3; | |
228 | int idx_word = 5; | |
229 | return bgp_static_set_safi (SAFI_ENCAP, vty, argv[idx_ipv4]->arg, argv[idx_rd]->arg, argv[idx_word]->arg, NULL); | |
587ff0fd LB |
230 | } |
231 | ||
232 | /* For testing purpose, static route of ENCAP. */ | |
233 | DEFUN (no_encap_network, | |
234 | no_encap_network_cmd, | |
235 | "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD", | |
236 | NO_STR | |
237 | "Specify a network to announce via BGP\n" | |
0c7b1b01 | 238 | "IPv4 prefix\n" |
587ff0fd LB |
239 | "Specify Route Distinguisher\n" |
240 | "ENCAP Route Distinguisher\n" | |
241 | "BGP tag\n" | |
242 | "tag value\n") | |
243 | { | |
5bf15956 DW |
244 | int idx_ipv4 = 2; |
245 | int idx_rd = 4; | |
246 | int idx_word = 6; | |
247 | return bgp_static_unset_safi (SAFI_ENCAP, vty, argv[idx_ipv4]->arg, argv[idx_rd]->arg, argv[idx_word]->arg); | |
587ff0fd LB |
248 | } |
249 | ||
250 | static int | |
251 | show_adj_route_encap (struct vty *vty, struct peer *peer, struct prefix_rd *prd) | |
252 | { | |
253 | struct bgp *bgp; | |
254 | struct bgp_table *table; | |
255 | struct bgp_node *rn; | |
256 | struct bgp_node *rm; | |
257 | struct attr *attr; | |
258 | int rd_header; | |
259 | int header = 1; | |
260 | char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s"; | |
261 | ||
262 | bgp = bgp_get_default (); | |
263 | if (bgp == NULL) | |
264 | { | |
265 | vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); | |
266 | return CMD_WARNING; | |
267 | } | |
268 | ||
269 | for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_ENCAP]); rn; | |
270 | rn = bgp_route_next (rn)) | |
271 | { | |
272 | if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0) | |
273 | continue; | |
274 | ||
275 | if ((table = rn->info) != NULL) | |
276 | { | |
277 | rd_header = 1; | |
278 | ||
279 | for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm)) | |
280 | if ((attr = rm->info) != NULL) | |
281 | { | |
282 | if (header) | |
283 | { | |
284 | vty_out (vty, "BGP table version is 0, local router ID is %s%s", | |
285 | inet_ntoa (bgp->router_id), VTY_NEWLINE); | |
286 | vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", | |
287 | VTY_NEWLINE); | |
288 | vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", | |
289 | VTY_NEWLINE, VTY_NEWLINE); | |
290 | vty_out (vty, v4_header, VTY_NEWLINE); | |
291 | header = 0; | |
292 | } | |
293 | ||
294 | if (rd_header) | |
295 | { | |
296 | u_int16_t type; | |
297 | struct rd_as rd_as; | |
298 | struct rd_ip rd_ip; | |
299 | u_char *pnt; | |
300 | ||
301 | pnt = rn->p.u.val; | |
302 | ||
303 | vty_out (vty, "Route Distinguisher: "); | |
304 | ||
305 | /* Decode RD type. */ | |
306 | type = decode_rd_type (pnt); | |
307 | ||
308 | switch (type) { | |
309 | ||
310 | case RD_TYPE_AS: | |
311 | decode_rd_as (pnt + 2, &rd_as); | |
312 | vty_out (vty, "%u:%d", rd_as.as, rd_as.val); | |
313 | break; | |
314 | ||
315 | case RD_TYPE_IP: | |
316 | decode_rd_ip (pnt + 2, &rd_ip); | |
317 | vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val); | |
318 | break; | |
319 | ||
320 | default: | |
321 | vty_out (vty, "unknown RD type"); | |
322 | } | |
323 | ||
324 | ||
325 | vty_out (vty, "%s", VTY_NEWLINE); | |
326 | rd_header = 0; | |
327 | } | |
328 | route_vty_out_tmp (vty, &rm->p, attr, SAFI_ENCAP, 0, NULL); | |
329 | } | |
330 | } | |
331 | } | |
332 | return CMD_SUCCESS; | |
333 | } | |
334 | ||
335 | enum bgp_show_type | |
336 | { | |
337 | bgp_show_type_normal, | |
338 | bgp_show_type_regexp, | |
339 | bgp_show_type_prefix_list, | |
340 | bgp_show_type_filter_list, | |
341 | bgp_show_type_neighbor, | |
342 | bgp_show_type_cidr_only, | |
343 | bgp_show_type_prefix_longer, | |
344 | bgp_show_type_community_all, | |
345 | bgp_show_type_community, | |
346 | bgp_show_type_community_exact, | |
347 | bgp_show_type_community_list, | |
348 | bgp_show_type_community_list_exact | |
349 | }; | |
350 | ||
351 | static int | |
352 | bgp_show_encap ( | |
353 | struct vty *vty, | |
354 | afi_t afi, | |
355 | struct prefix_rd *prd, | |
356 | enum bgp_show_type type, | |
357 | void *output_arg, | |
358 | int tags) | |
359 | { | |
360 | struct bgp *bgp; | |
361 | struct bgp_table *table; | |
362 | struct bgp_node *rn; | |
363 | struct bgp_node *rm; | |
364 | struct bgp_info *ri; | |
365 | int rd_header; | |
366 | int header = 1; | |
367 | char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s"; | |
368 | char v4_header_tag[] = " Network Next Hop In tag/Out tag%s"; | |
369 | ||
370 | unsigned long output_count = 0; | |
371 | unsigned long total_count = 0; | |
372 | ||
373 | bgp = bgp_get_default (); | |
374 | if (bgp == NULL) | |
375 | { | |
376 | vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); | |
377 | return CMD_WARNING; | |
378 | } | |
379 | ||
380 | if ((afi != AFI_IP) && (afi != AFI_IP6)) { | |
381 | vty_out (vty, "Afi %d not supported%s", afi, VTY_NEWLINE); | |
382 | return CMD_WARNING; | |
383 | } | |
384 | ||
385 | for (rn = bgp_table_top (bgp->rib[afi][SAFI_ENCAP]); rn; rn = bgp_route_next (rn)) | |
386 | { | |
387 | if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0) | |
388 | continue; | |
389 | ||
390 | if ((table = rn->info) != NULL) | |
391 | { | |
392 | rd_header = 1; | |
393 | ||
394 | for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm)) | |
395 | for (ri = rm->info; ri; ri = ri->next) | |
396 | { | |
397 | total_count++; | |
398 | if (type == bgp_show_type_neighbor) | |
399 | { | |
400 | union sockunion *su = output_arg; | |
401 | ||
402 | if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su)) | |
403 | continue; | |
404 | } | |
405 | if (header) | |
406 | { | |
407 | if (tags) | |
408 | vty_out (vty, v4_header_tag, VTY_NEWLINE); | |
409 | else | |
410 | { | |
411 | vty_out (vty, "BGP table version is 0, local router ID is %s%s", | |
412 | inet_ntoa (bgp->router_id), VTY_NEWLINE); | |
413 | vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", | |
414 | VTY_NEWLINE); | |
415 | vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", | |
416 | VTY_NEWLINE, VTY_NEWLINE); | |
417 | vty_out (vty, v4_header, VTY_NEWLINE); | |
418 | } | |
419 | header = 0; | |
420 | } | |
421 | ||
422 | if (rd_header) | |
423 | { | |
424 | u_int16_t type; | |
425 | struct rd_as rd_as; | |
426 | struct rd_ip rd_ip; | |
427 | u_char *pnt; | |
428 | ||
429 | pnt = rn->p.u.val; | |
430 | ||
431 | /* Decode RD type. */ | |
432 | type = decode_rd_type (pnt); | |
433 | ||
434 | vty_out (vty, "Route Distinguisher: "); | |
435 | ||
436 | switch (type) { | |
437 | ||
438 | case RD_TYPE_AS: | |
439 | decode_rd_as (pnt + 2, &rd_as); | |
440 | vty_out (vty, "%u:%d", rd_as.as, rd_as.val); | |
441 | break; | |
442 | ||
443 | case RD_TYPE_IP: | |
444 | decode_rd_ip (pnt + 2, &rd_ip); | |
445 | vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val); | |
446 | break; | |
447 | ||
448 | default: | |
449 | vty_out (vty, "Unknown RD type"); | |
450 | break; | |
451 | } | |
452 | ||
453 | vty_out (vty, "%s", VTY_NEWLINE); | |
454 | rd_header = 0; | |
455 | } | |
456 | if (tags) | |
457 | route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_ENCAP, NULL); | |
458 | else | |
459 | route_vty_out (vty, &rm->p, ri, 0, SAFI_ENCAP, NULL); | |
460 | output_count++; | |
461 | } | |
462 | } | |
463 | } | |
464 | ||
465 | if (output_count == 0) | |
466 | { | |
467 | vty_out (vty, "No prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE); | |
468 | } | |
469 | else | |
470 | vty_out (vty, "%sDisplayed %ld out of %ld total prefixes%s", | |
471 | VTY_NEWLINE, output_count, total_count, VTY_NEWLINE); | |
472 | ||
473 | return CMD_SUCCESS; | |
474 | } | |
475 | ||
476 | DEFUN (show_bgp_ipv4_encap, | |
477 | show_bgp_ipv4_encap_cmd, | |
716b2d8a | 478 | "show [ip] bgp ipv4 encap", |
587ff0fd | 479 | SHOW_STR |
716b2d8a | 480 | IP_STR |
587ff0fd LB |
481 | BGP_STR |
482 | "Address Family\n" | |
483 | "Display ENCAP NLRI specific information\n") | |
484 | { | |
485 | return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 0); | |
486 | } | |
487 | #ifdef HAVE_IPV6 | |
488 | DEFUN (show_bgp_ipv6_encap, | |
489 | show_bgp_ipv6_encap_cmd, | |
716b2d8a | 490 | "show [ip] bgp ipv6 encap", |
587ff0fd | 491 | SHOW_STR |
716b2d8a | 492 | IP_STR |
587ff0fd LB |
493 | BGP_STR |
494 | "Address Family\n" | |
495 | "Display ENCAP NLRI specific information\n") | |
496 | { | |
497 | return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL, 0); | |
498 | } | |
499 | #endif | |
500 | ||
501 | DEFUN (show_bgp_ipv4_encap_rd, | |
502 | show_bgp_ipv4_encap_rd_cmd, | |
716b2d8a | 503 | "show [ip] bgp ipv4 encap rd ASN:nn_or_IP-address:nn", |
587ff0fd | 504 | SHOW_STR |
716b2d8a | 505 | IP_STR |
587ff0fd LB |
506 | BGP_STR |
507 | "Address Family\n" | |
508 | "Display ENCAP NLRI specific information\n" | |
509 | "Display information for a route distinguisher\n" | |
510 | "ENCAP Route Distinguisher\n") | |
511 | { | |
5bf15956 | 512 | int idx_rd = 5; |
587ff0fd LB |
513 | int ret; |
514 | struct prefix_rd prd; | |
515 | ||
5bf15956 | 516 | ret = str2prefix_rd (argv[idx_rd]->arg, &prd); |
587ff0fd LB |
517 | if (! ret) |
518 | { | |
519 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
520 | return CMD_WARNING; | |
521 | } | |
522 | return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 0); | |
523 | } | |
524 | #ifdef HAVE_IPV6 | |
525 | DEFUN (show_bgp_ipv6_encap_rd, | |
526 | show_bgp_ipv6_encap_rd_cmd, | |
716b2d8a | 527 | "show [ip] bgp ipv6 encap rd ASN:nn_or_IP-address:nn", |
587ff0fd | 528 | SHOW_STR |
716b2d8a | 529 | IP_STR |
587ff0fd LB |
530 | BGP_STR |
531 | "Address Family\n" | |
532 | "Display ENCAP NLRI specific information\n" | |
533 | "Display information for a route distinguisher\n" | |
534 | "ENCAP Route Distinguisher\n" | |
535 | "Display BGP tags for prefixes\n") | |
536 | { | |
5bf15956 | 537 | int idx_rd = 5; |
587ff0fd LB |
538 | int ret; |
539 | struct prefix_rd prd; | |
540 | ||
5bf15956 | 541 | ret = str2prefix_rd (argv[idx_rd]->arg, &prd); |
587ff0fd LB |
542 | if (! ret) |
543 | { | |
544 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
545 | return CMD_WARNING; | |
546 | } | |
547 | return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 0); | |
548 | } | |
549 | #endif | |
550 | ||
551 | DEFUN (show_bgp_ipv4_encap_tags, | |
552 | show_bgp_ipv4_encap_tags_cmd, | |
716b2d8a | 553 | "show [ip] bgp ipv4 encap tags", |
587ff0fd | 554 | SHOW_STR |
716b2d8a | 555 | IP_STR |
587ff0fd LB |
556 | BGP_STR |
557 | "Address Family\n" | |
558 | "Display ENCAP NLRI specific information\n" | |
559 | "Display BGP tags for prefixes\n") | |
560 | { | |
561 | return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 1); | |
562 | } | |
563 | #ifdef HAVE_IPV6 | |
564 | DEFUN (show_bgp_ipv6_encap_tags, | |
565 | show_bgp_ipv6_encap_tags_cmd, | |
716b2d8a | 566 | "show [ip] bgp ipv6 encap tags", |
587ff0fd | 567 | SHOW_STR |
716b2d8a | 568 | IP_STR |
587ff0fd LB |
569 | BGP_STR |
570 | "Address Family\n" | |
571 | "Display ENCAP NLRI specific information\n" | |
572 | "Display BGP tags for prefixes\n") | |
573 | { | |
574 | return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL, 1); | |
575 | } | |
576 | #endif | |
577 | ||
578 | DEFUN (show_bgp_ipv4_encap_rd_tags, | |
579 | show_bgp_ipv4_encap_rd_tags_cmd, | |
716b2d8a | 580 | "show [ip] bgp ipv4 encap rd ASN:nn_or_IP-address:nn tags", |
587ff0fd | 581 | SHOW_STR |
716b2d8a | 582 | IP_STR |
587ff0fd LB |
583 | BGP_STR |
584 | "Address Family\n" | |
585 | "Display ENCAP NLRI specific information\n" | |
586 | "Display information for a route distinguisher\n" | |
587 | "ENCAP Route Distinguisher\n" | |
588 | "Display BGP tags for prefixes\n") | |
589 | { | |
5bf15956 | 590 | int idx_rd = 5; |
587ff0fd LB |
591 | int ret; |
592 | struct prefix_rd prd; | |
593 | ||
5bf15956 | 594 | ret = str2prefix_rd (argv[idx_rd]->arg, &prd); |
587ff0fd LB |
595 | if (! ret) |
596 | { | |
597 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
598 | return CMD_WARNING; | |
599 | } | |
600 | return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 1); | |
601 | } | |
602 | #ifdef HAVE_IPV6 | |
603 | DEFUN (show_bgp_ipv6_encap_rd_tags, | |
604 | show_bgp_ipv6_encap_rd_tags_cmd, | |
716b2d8a | 605 | "show [ip] bgp ipv6 encap rd ASN:nn_or_IP-address:nn tags", |
587ff0fd | 606 | SHOW_STR |
716b2d8a | 607 | IP_STR |
587ff0fd LB |
608 | BGP_STR |
609 | "Address Family\n" | |
610 | "Display ENCAP NLRI specific information\n" | |
611 | "Display information for a route distinguisher\n" | |
612 | "ENCAP Route Distinguisher\n" | |
613 | "Display BGP tags for prefixes\n") | |
614 | { | |
5bf15956 | 615 | int idx_rd = 5; |
587ff0fd LB |
616 | int ret; |
617 | struct prefix_rd prd; | |
618 | ||
5bf15956 | 619 | ret = str2prefix_rd (argv[idx_rd]->arg, &prd); |
587ff0fd LB |
620 | if (! ret) |
621 | { | |
622 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
623 | return CMD_WARNING; | |
624 | } | |
625 | return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 1); | |
626 | } | |
627 | #endif | |
628 | ||
629 | DEFUN (show_bgp_ipv4_encap_neighbor_routes, | |
630 | show_bgp_ipv4_encap_neighbor_routes_cmd, | |
716b2d8a | 631 | "show [ip] bgp ipv4 encap neighbors A.B.C.D routes", |
587ff0fd | 632 | SHOW_STR |
716b2d8a | 633 | IP_STR |
587ff0fd LB |
634 | BGP_STR |
635 | "Address Family\n" | |
636 | "Display ENCAP NLRI specific information\n" | |
637 | "Detailed information on TCP and BGP neighbor connections\n" | |
638 | "Neighbor to display information about\n" | |
639 | "Display routes learned from neighbor\n") | |
640 | { | |
5bf15956 | 641 | int idx_peer = 5; |
b6175e0c | 642 | union sockunion su; |
587ff0fd | 643 | struct peer *peer; |
b6175e0c | 644 | |
39e92c06 | 645 | if (sockunion_str2su (argv[idx_peer]->arg)) |
587ff0fd | 646 | { |
5bf15956 | 647 | vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); |
587ff0fd LB |
648 | return CMD_WARNING; |
649 | } | |
650 | ||
b6175e0c | 651 | peer = peer_lookup (NULL, &su); |
587ff0fd LB |
652 | if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP]) |
653 | { | |
654 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
655 | return CMD_WARNING; | |
656 | } | |
657 | ||
b6175e0c | 658 | return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_neighbor, &su, 0); |
587ff0fd LB |
659 | } |
660 | #ifdef HAVE_IPV6 | |
661 | DEFUN (show_bgp_ipv6_encap_neighbor_routes, | |
662 | show_bgp_ipv6_encap_neighbor_routes_cmd, | |
716b2d8a | 663 | "show [ip] bgp ipv6 encap neighbors A.B.C.D routes", |
587ff0fd | 664 | SHOW_STR |
716b2d8a | 665 | IP_STR |
587ff0fd LB |
666 | BGP_STR |
667 | "Address Family\n" | |
668 | "Display ENCAP NLRI specific information\n" | |
669 | "Detailed information on TCP and BGP neighbor connections\n" | |
670 | "Neighbor to display information about\n" | |
671 | "Display routes learned from neighbor\n") | |
672 | { | |
5bf15956 | 673 | int idx_peer = 5; |
b6175e0c | 674 | union sockunion su; |
587ff0fd LB |
675 | struct peer *peer; |
676 | ||
39e92c06 | 677 | if (str2sockunion(argv[idx_peer]->arg, &su)) |
587ff0fd | 678 | { |
5bf15956 | 679 | vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); |
587ff0fd LB |
680 | return CMD_WARNING; |
681 | } | |
682 | ||
b6175e0c | 683 | peer = peer_lookup (NULL, &su); |
587ff0fd LB |
684 | if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP]) |
685 | { | |
686 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
687 | return CMD_WARNING; | |
688 | } | |
689 | ||
b6175e0c | 690 | return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_neighbor, &su, 0); |
587ff0fd LB |
691 | } |
692 | #endif | |
693 | ||
694 | DEFUN (show_bgp_ipv4_encap_rd_neighbor_routes, | |
695 | show_bgp_ipv4_encap_rd_neighbor_routes_cmd, | |
716b2d8a | 696 | "show [ip] bgp ipv4 encap rd ASN:nn_or_IP-address:nn neighbors <A.B.C.D|X:X::X:X> routes", |
587ff0fd | 697 | SHOW_STR |
716b2d8a | 698 | IP_STR |
587ff0fd LB |
699 | BGP_STR |
700 | "Address Family\n" | |
701 | "Display ENCAP NLRI specific information\n" | |
702 | "Display information for a route distinguisher\n" | |
703 | "ENCAP Route Distinguisher\n" | |
704 | "Detailed information on TCP and BGP neighbor connections\n" | |
705 | "Neighbor to display information about\n" | |
706 | "Neighbor to display information about\n" | |
707 | "Display routes learned from neighbor\n") | |
708 | { | |
5bf15956 DW |
709 | int idx_rd = 5; |
710 | int idx_peer = 7; | |
587ff0fd | 711 | int ret; |
b6175e0c | 712 | union sockunion su; |
587ff0fd LB |
713 | struct peer *peer; |
714 | struct prefix_rd prd; | |
715 | ||
5bf15956 | 716 | ret = str2prefix_rd (argv[idx_rd]->arg, &prd); |
587ff0fd LB |
717 | if (! ret) |
718 | { | |
719 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
720 | return CMD_WARNING; | |
721 | } | |
722 | ||
39e92c06 | 723 | if (str2sockunion(argv[idx_peer]->arg, &su)) |
587ff0fd | 724 | { |
5bf15956 | 725 | vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); |
587ff0fd LB |
726 | return CMD_WARNING; |
727 | } | |
728 | ||
b6175e0c | 729 | peer = peer_lookup (NULL, &su); |
587ff0fd LB |
730 | if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP]) |
731 | { | |
732 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
733 | return CMD_WARNING; | |
734 | } | |
735 | ||
b6175e0c | 736 | return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_neighbor, &su, 0); |
587ff0fd LB |
737 | } |
738 | #ifdef HAVE_IPV6 | |
739 | DEFUN (show_bgp_ipv6_encap_rd_neighbor_routes, | |
740 | show_bgp_ipv6_encap_rd_neighbor_routes_cmd, | |
716b2d8a | 741 | "show [ip] bgp ipv6 encap rd ASN:nn_or_IP-address:nn neighbors <A.B.C.D|X:X::X:X> routes", |
587ff0fd | 742 | SHOW_STR |
716b2d8a | 743 | IP_STR |
587ff0fd LB |
744 | BGP_STR |
745 | "Address Family\n" | |
746 | "Display ENCAP NLRI specific information\n" | |
747 | "Display information for a route distinguisher\n" | |
748 | "ENCAP Route Distinguisher\n" | |
749 | "Detailed information on TCP and BGP neighbor connections\n" | |
750 | "Neighbor to display information about\n" | |
751 | "Neighbor to display information about\n" | |
752 | "Display routes learned from neighbor\n") | |
753 | { | |
5bf15956 DW |
754 | int idx_rd = 5; |
755 | int idx_peer = 7; | |
587ff0fd | 756 | int ret; |
b6175e0c | 757 | union sockunion su; |
587ff0fd LB |
758 | struct peer *peer; |
759 | struct prefix_rd prd; | |
760 | ||
5bf15956 | 761 | ret = str2prefix_rd (argv[idx_rd]->arg, &prd); |
587ff0fd LB |
762 | if (! ret) |
763 | { | |
764 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
765 | return CMD_WARNING; | |
766 | } | |
767 | ||
39e92c06 | 768 | if (str2sockunion(argv[idx_peer]->arg, &su)) |
587ff0fd | 769 | { |
5bf15956 | 770 | vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); |
587ff0fd LB |
771 | return CMD_WARNING; |
772 | } | |
773 | ||
b6175e0c | 774 | peer = peer_lookup (NULL, &su); |
587ff0fd LB |
775 | if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP]) |
776 | { | |
777 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
778 | return CMD_WARNING; | |
779 | } | |
780 | ||
b6175e0c | 781 | return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_neighbor, &su, 0); |
587ff0fd LB |
782 | } |
783 | #endif | |
784 | ||
785 | DEFUN (show_bgp_ipv4_encap_neighbor_advertised_routes, | |
786 | show_bgp_ipv4_encap_neighbor_advertised_routes_cmd, | |
716b2d8a | 787 | "show [ip] bgp ipv4 encap neighbors A.B.C.D advertised-routes", |
587ff0fd | 788 | SHOW_STR |
716b2d8a | 789 | IP_STR |
587ff0fd LB |
790 | BGP_STR |
791 | "Address Family\n" | |
792 | "Display ENCAP NLRI specific information\n" | |
793 | "Detailed information on TCP and BGP neighbor connections\n" | |
794 | "Neighbor to display information about\n" | |
795 | "Display the routes advertised to a BGP neighbor\n") | |
796 | { | |
5bf15956 | 797 | int idx_peer = 5; |
587ff0fd LB |
798 | int ret; |
799 | struct peer *peer; | |
800 | union sockunion su; | |
801 | ||
5bf15956 | 802 | ret = str2sockunion (argv[idx_peer]->arg, &su); |
587ff0fd LB |
803 | if (ret < 0) |
804 | { | |
5bf15956 | 805 | vty_out (vty, "%% Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); |
587ff0fd LB |
806 | return CMD_WARNING; |
807 | } | |
808 | peer = peer_lookup (NULL, &su); | |
809 | if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP]) | |
810 | { | |
811 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
812 | return CMD_WARNING; | |
813 | } | |
814 | ||
815 | return show_adj_route_encap (vty, peer, NULL); | |
816 | } | |
817 | #ifdef HAVE_IPV6 | |
818 | DEFUN (show_bgp_ipv6_encap_neighbor_advertised_routes, | |
819 | show_bgp_ipv6_encap_neighbor_advertised_routes_cmd, | |
716b2d8a | 820 | "show [ip] bgp ipv6 encap neighbors A.B.C.D advertised-routes", |
587ff0fd | 821 | SHOW_STR |
716b2d8a | 822 | IP_STR |
587ff0fd LB |
823 | BGP_STR |
824 | "Address Family\n" | |
825 | "Display ENCAP NLRI specific information\n" | |
826 | "Detailed information on TCP and BGP neighbor connections\n" | |
827 | "Neighbor to display information about\n" | |
828 | "Display the routes advertised to a BGP neighbor\n") | |
829 | { | |
5bf15956 | 830 | int idx_peer = 5; |
587ff0fd LB |
831 | int ret; |
832 | struct peer *peer; | |
833 | union sockunion su; | |
834 | ||
5bf15956 | 835 | ret = str2sockunion (argv[idx_peer]->arg, &su); |
587ff0fd LB |
836 | if (ret < 0) |
837 | { | |
5bf15956 | 838 | vty_out (vty, "%% Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); |
587ff0fd LB |
839 | return CMD_WARNING; |
840 | } | |
841 | peer = peer_lookup (NULL, &su); | |
842 | if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP]) | |
843 | { | |
844 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
845 | return CMD_WARNING; | |
846 | } | |
847 | ||
848 | return show_adj_route_encap (vty, peer, NULL); | |
849 | } | |
850 | #endif | |
851 | ||
852 | DEFUN (show_bgp_ipv4_encap_rd_neighbor_advertised_routes, | |
853 | show_bgp_ipv4_encap_rd_neighbor_advertised_routes_cmd, | |
716b2d8a | 854 | "show [ip] bgp ipv4 encap rd ASN:nn_or_IP-address:nn neighbors <A.B.C.D|X:X::X:X> advertised-routes", |
587ff0fd | 855 | SHOW_STR |
716b2d8a | 856 | IP_STR |
587ff0fd LB |
857 | BGP_STR |
858 | "Address Family\n" | |
859 | "Display ENCAP NLRI specific information\n" | |
860 | "Display information for a route distinguisher\n" | |
861 | "ENCAP Route Distinguisher\n" | |
862 | "Detailed information on TCP and BGP neighbor connections\n" | |
863 | "Neighbor to display information about\n" | |
864 | "Neighbor to display information about\n" | |
865 | "Display the routes advertised to a BGP neighbor\n") | |
866 | { | |
5bf15956 DW |
867 | int idx_rd = 5; |
868 | int idx_peer = 7; | |
587ff0fd LB |
869 | int ret; |
870 | struct peer *peer; | |
871 | struct prefix_rd prd; | |
872 | union sockunion su; | |
873 | ||
5bf15956 | 874 | ret = str2sockunion (argv[idx_peer]->arg, &su); |
587ff0fd LB |
875 | if (ret < 0) |
876 | { | |
5bf15956 | 877 | vty_out (vty, "%% Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); |
587ff0fd LB |
878 | return CMD_WARNING; |
879 | } | |
880 | peer = peer_lookup (NULL, &su); | |
881 | if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP]) | |
882 | { | |
883 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
884 | return CMD_WARNING; | |
885 | } | |
886 | ||
5bf15956 | 887 | ret = str2prefix_rd (argv[idx_rd]->arg, &prd); |
587ff0fd LB |
888 | if (! ret) |
889 | { | |
890 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
891 | return CMD_WARNING; | |
892 | } | |
893 | ||
894 | return show_adj_route_encap (vty, peer, &prd); | |
895 | } | |
896 | #ifdef HAVE_IPV6 | |
897 | DEFUN (show_bgp_ipv6_encap_rd_neighbor_advertised_routes, | |
898 | show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd, | |
716b2d8a | 899 | "show [ip] bgp ipv6 encap rd ASN:nn_or_IP-address:nn neighbors <A.B.C.D|X:X::X:X> advertised-routes", |
587ff0fd | 900 | SHOW_STR |
716b2d8a | 901 | IP_STR |
587ff0fd LB |
902 | BGP_STR |
903 | "Address Family\n" | |
904 | "Display ENCAP NLRI specific information\n" | |
905 | "Display information for a route distinguisher\n" | |
906 | "ENCAP Route Distinguisher\n" | |
907 | "Detailed information on TCP and BGP neighbor connections\n" | |
908 | "Neighbor to display information about\n" | |
909 | "Neighbor to display information about\n" | |
910 | "Display the routes advertised to a BGP neighbor\n") | |
911 | { | |
5bf15956 DW |
912 | int idx_rd = 5; |
913 | int idx_peer = 7; | |
587ff0fd LB |
914 | int ret; |
915 | struct peer *peer; | |
916 | struct prefix_rd prd; | |
917 | union sockunion su; | |
918 | ||
5bf15956 | 919 | ret = str2sockunion (argv[idx_peer]->arg, &su); |
587ff0fd LB |
920 | if (ret < 0) |
921 | { | |
5bf15956 | 922 | vty_out (vty, "%% Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); |
587ff0fd LB |
923 | return CMD_WARNING; |
924 | } | |
925 | peer = peer_lookup (NULL, &su); | |
926 | if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP]) | |
927 | { | |
928 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
929 | return CMD_WARNING; | |
930 | } | |
931 | ||
5bf15956 | 932 | ret = str2prefix_rd (argv[idx_rd]->arg, &prd); |
587ff0fd LB |
933 | if (! ret) |
934 | { | |
935 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
936 | return CMD_WARNING; | |
937 | } | |
938 | ||
939 | return show_adj_route_encap (vty, peer, &prd); | |
940 | } | |
941 | #endif | |
942 | ||
943 | void | |
944 | bgp_encap_init (void) | |
945 | { | |
8b1fb8be LB |
946 | install_element (BGP_ENCAP_NODE, &encap_network_cmd); |
947 | install_element (BGP_ENCAP_NODE, &no_encap_network_cmd); | |
587ff0fd LB |
948 | |
949 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_cmd); | |
950 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_cmd); | |
951 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_tags_cmd); | |
952 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_tags_cmd); | |
953 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_neighbor_routes_cmd); | |
954 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_neighbor_routes_cmd); | |
955 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_neighbor_advertised_routes_cmd); | |
956 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_neighbor_advertised_routes_cmd); | |
957 | ||
958 | #ifdef HAVE_IPV6 | |
959 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_cmd); | |
960 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_cmd); | |
961 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_tags_cmd); | |
962 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_tags_cmd); | |
963 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_neighbor_routes_cmd); | |
964 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_neighbor_routes_cmd); | |
965 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_neighbor_advertised_routes_cmd); | |
966 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd); | |
967 | #endif | |
587ff0fd | 968 | } |