]>
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 LB |
50 | #endif |
51 | ||
587ff0fd LB |
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" | |
220 | "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n" | |
221 | "Specify Route Distinguisher\n" | |
222 | "ENCAP Route Distinguisher\n" | |
223 | "BGP tag\n" | |
224 | "tag value\n") | |
225 | { | |
226 | return bgp_static_set_safi (SAFI_ENCAP, vty, argv[0], argv[1], argv[2], NULL); | |
227 | } | |
228 | ||
229 | /* For testing purpose, static route of ENCAP. */ | |
230 | DEFUN (no_encap_network, | |
231 | no_encap_network_cmd, | |
232 | "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD", | |
233 | NO_STR | |
234 | "Specify a network to announce via BGP\n" | |
235 | "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n" | |
236 | "Specify Route Distinguisher\n" | |
237 | "ENCAP Route Distinguisher\n" | |
238 | "BGP tag\n" | |
239 | "tag value\n") | |
240 | { | |
241 | return bgp_static_unset_safi (SAFI_ENCAP, vty, argv[0], argv[1], argv[2]); | |
242 | } | |
243 | ||
244 | static int | |
245 | show_adj_route_encap (struct vty *vty, struct peer *peer, struct prefix_rd *prd) | |
246 | { | |
247 | struct bgp *bgp; | |
248 | struct bgp_table *table; | |
249 | struct bgp_node *rn; | |
250 | struct bgp_node *rm; | |
251 | struct attr *attr; | |
252 | int rd_header; | |
253 | int header = 1; | |
254 | char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s"; | |
255 | ||
256 | bgp = bgp_get_default (); | |
257 | if (bgp == NULL) | |
258 | { | |
259 | vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); | |
260 | return CMD_WARNING; | |
261 | } | |
262 | ||
263 | for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_ENCAP]); rn; | |
264 | rn = bgp_route_next (rn)) | |
265 | { | |
266 | if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0) | |
267 | continue; | |
268 | ||
269 | if ((table = rn->info) != NULL) | |
270 | { | |
271 | rd_header = 1; | |
272 | ||
273 | for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm)) | |
274 | if ((attr = rm->info) != NULL) | |
275 | { | |
276 | if (header) | |
277 | { | |
278 | vty_out (vty, "BGP table version is 0, local router ID is %s%s", | |
279 | inet_ntoa (bgp->router_id), VTY_NEWLINE); | |
280 | vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", | |
281 | VTY_NEWLINE); | |
282 | vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", | |
283 | VTY_NEWLINE, VTY_NEWLINE); | |
284 | vty_out (vty, v4_header, VTY_NEWLINE); | |
285 | header = 0; | |
286 | } | |
287 | ||
288 | if (rd_header) | |
289 | { | |
290 | u_int16_t type; | |
291 | struct rd_as rd_as; | |
292 | struct rd_ip rd_ip; | |
293 | u_char *pnt; | |
294 | ||
295 | pnt = rn->p.u.val; | |
296 | ||
297 | vty_out (vty, "Route Distinguisher: "); | |
298 | ||
299 | /* Decode RD type. */ | |
300 | type = decode_rd_type (pnt); | |
301 | ||
302 | switch (type) { | |
303 | ||
304 | case RD_TYPE_AS: | |
305 | decode_rd_as (pnt + 2, &rd_as); | |
306 | vty_out (vty, "%u:%d", rd_as.as, rd_as.val); | |
307 | break; | |
308 | ||
309 | case RD_TYPE_IP: | |
310 | decode_rd_ip (pnt + 2, &rd_ip); | |
311 | vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val); | |
312 | break; | |
313 | ||
314 | default: | |
315 | vty_out (vty, "unknown RD type"); | |
316 | } | |
317 | ||
318 | ||
319 | vty_out (vty, "%s", VTY_NEWLINE); | |
320 | rd_header = 0; | |
321 | } | |
322 | route_vty_out_tmp (vty, &rm->p, attr, SAFI_ENCAP, 0, NULL); | |
323 | } | |
324 | } | |
325 | } | |
326 | return CMD_SUCCESS; | |
327 | } | |
328 | ||
329 | enum bgp_show_type | |
330 | { | |
331 | bgp_show_type_normal, | |
332 | bgp_show_type_regexp, | |
333 | bgp_show_type_prefix_list, | |
334 | bgp_show_type_filter_list, | |
335 | bgp_show_type_neighbor, | |
336 | bgp_show_type_cidr_only, | |
337 | bgp_show_type_prefix_longer, | |
338 | bgp_show_type_community_all, | |
339 | bgp_show_type_community, | |
340 | bgp_show_type_community_exact, | |
341 | bgp_show_type_community_list, | |
342 | bgp_show_type_community_list_exact | |
343 | }; | |
344 | ||
345 | static int | |
346 | bgp_show_encap ( | |
347 | struct vty *vty, | |
348 | afi_t afi, | |
349 | struct prefix_rd *prd, | |
350 | enum bgp_show_type type, | |
351 | void *output_arg, | |
352 | int tags) | |
353 | { | |
354 | struct bgp *bgp; | |
355 | struct bgp_table *table; | |
356 | struct bgp_node *rn; | |
357 | struct bgp_node *rm; | |
358 | struct bgp_info *ri; | |
359 | int rd_header; | |
360 | int header = 1; | |
361 | char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s"; | |
362 | char v4_header_tag[] = " Network Next Hop In tag/Out tag%s"; | |
363 | ||
364 | unsigned long output_count = 0; | |
365 | unsigned long total_count = 0; | |
366 | ||
367 | bgp = bgp_get_default (); | |
368 | if (bgp == NULL) | |
369 | { | |
370 | vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); | |
371 | return CMD_WARNING; | |
372 | } | |
373 | ||
374 | if ((afi != AFI_IP) && (afi != AFI_IP6)) { | |
375 | vty_out (vty, "Afi %d not supported%s", afi, VTY_NEWLINE); | |
376 | return CMD_WARNING; | |
377 | } | |
378 | ||
379 | for (rn = bgp_table_top (bgp->rib[afi][SAFI_ENCAP]); rn; rn = bgp_route_next (rn)) | |
380 | { | |
381 | if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0) | |
382 | continue; | |
383 | ||
384 | if ((table = rn->info) != NULL) | |
385 | { | |
386 | rd_header = 1; | |
387 | ||
388 | for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm)) | |
389 | for (ri = rm->info; ri; ri = ri->next) | |
390 | { | |
391 | total_count++; | |
392 | if (type == bgp_show_type_neighbor) | |
393 | { | |
394 | union sockunion *su = output_arg; | |
395 | ||
396 | if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su)) | |
397 | continue; | |
398 | } | |
399 | if (header) | |
400 | { | |
401 | if (tags) | |
402 | vty_out (vty, v4_header_tag, VTY_NEWLINE); | |
403 | else | |
404 | { | |
405 | vty_out (vty, "BGP table version is 0, local router ID is %s%s", | |
406 | inet_ntoa (bgp->router_id), VTY_NEWLINE); | |
407 | vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", | |
408 | VTY_NEWLINE); | |
409 | vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", | |
410 | VTY_NEWLINE, VTY_NEWLINE); | |
411 | vty_out (vty, v4_header, VTY_NEWLINE); | |
412 | } | |
413 | header = 0; | |
414 | } | |
415 | ||
416 | if (rd_header) | |
417 | { | |
418 | u_int16_t type; | |
419 | struct rd_as rd_as; | |
420 | struct rd_ip rd_ip; | |
421 | u_char *pnt; | |
422 | ||
423 | pnt = rn->p.u.val; | |
424 | ||
425 | /* Decode RD type. */ | |
426 | type = decode_rd_type (pnt); | |
427 | ||
428 | vty_out (vty, "Route Distinguisher: "); | |
429 | ||
430 | switch (type) { | |
431 | ||
432 | case RD_TYPE_AS: | |
433 | decode_rd_as (pnt + 2, &rd_as); | |
434 | vty_out (vty, "%u:%d", rd_as.as, rd_as.val); | |
435 | break; | |
436 | ||
437 | case RD_TYPE_IP: | |
438 | decode_rd_ip (pnt + 2, &rd_ip); | |
439 | vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val); | |
440 | break; | |
441 | ||
442 | default: | |
443 | vty_out (vty, "Unknown RD type"); | |
444 | break; | |
445 | } | |
446 | ||
447 | vty_out (vty, "%s", VTY_NEWLINE); | |
448 | rd_header = 0; | |
449 | } | |
450 | if (tags) | |
451 | route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_ENCAP, NULL); | |
452 | else | |
453 | route_vty_out (vty, &rm->p, ri, 0, SAFI_ENCAP, NULL); | |
454 | output_count++; | |
455 | } | |
456 | } | |
457 | } | |
458 | ||
459 | if (output_count == 0) | |
460 | { | |
461 | vty_out (vty, "No prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE); | |
462 | } | |
463 | else | |
464 | vty_out (vty, "%sDisplayed %ld out of %ld total prefixes%s", | |
465 | VTY_NEWLINE, output_count, total_count, VTY_NEWLINE); | |
466 | ||
467 | return CMD_SUCCESS; | |
468 | } | |
469 | ||
470 | DEFUN (show_bgp_ipv4_encap, | |
471 | show_bgp_ipv4_encap_cmd, | |
472 | "show bgp ipv4 encap", | |
473 | SHOW_STR | |
474 | BGP_STR | |
475 | "Address Family\n" | |
476 | "Display ENCAP NLRI specific information\n") | |
477 | { | |
478 | return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 0); | |
479 | } | |
480 | #ifdef HAVE_IPV6 | |
481 | DEFUN (show_bgp_ipv6_encap, | |
482 | show_bgp_ipv6_encap_cmd, | |
483 | "show bgp ipv6 encap", | |
484 | SHOW_STR | |
485 | BGP_STR | |
486 | "Address Family\n" | |
487 | "Display ENCAP NLRI specific information\n") | |
488 | { | |
489 | return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL, 0); | |
490 | } | |
491 | #endif | |
492 | ||
493 | DEFUN (show_bgp_ipv4_encap_rd, | |
494 | show_bgp_ipv4_encap_rd_cmd, | |
495 | "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn", | |
496 | SHOW_STR | |
497 | BGP_STR | |
498 | "Address Family\n" | |
499 | "Display ENCAP NLRI specific information\n" | |
500 | "Display information for a route distinguisher\n" | |
501 | "ENCAP Route Distinguisher\n") | |
502 | { | |
503 | int ret; | |
504 | struct prefix_rd prd; | |
505 | ||
506 | ret = str2prefix_rd (argv[0], &prd); | |
507 | if (! ret) | |
508 | { | |
509 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
510 | return CMD_WARNING; | |
511 | } | |
512 | return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 0); | |
513 | } | |
514 | #ifdef HAVE_IPV6 | |
515 | DEFUN (show_bgp_ipv6_encap_rd, | |
516 | show_bgp_ipv6_encap_rd_cmd, | |
517 | "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn", | |
518 | SHOW_STR | |
519 | BGP_STR | |
520 | "Address Family\n" | |
521 | "Display ENCAP NLRI specific information\n" | |
522 | "Display information for a route distinguisher\n" | |
523 | "ENCAP Route Distinguisher\n" | |
524 | "Display BGP tags for prefixes\n") | |
525 | { | |
526 | int ret; | |
527 | struct prefix_rd prd; | |
528 | ||
529 | ret = str2prefix_rd (argv[0], &prd); | |
530 | if (! ret) | |
531 | { | |
532 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
533 | return CMD_WARNING; | |
534 | } | |
535 | return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 0); | |
536 | } | |
537 | #endif | |
538 | ||
539 | DEFUN (show_bgp_ipv4_encap_tags, | |
540 | show_bgp_ipv4_encap_tags_cmd, | |
541 | "show bgp ipv4 encap tags", | |
542 | SHOW_STR | |
543 | BGP_STR | |
544 | "Address Family\n" | |
545 | "Display ENCAP NLRI specific information\n" | |
546 | "Display BGP tags for prefixes\n") | |
547 | { | |
548 | return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 1); | |
549 | } | |
550 | #ifdef HAVE_IPV6 | |
551 | DEFUN (show_bgp_ipv6_encap_tags, | |
552 | show_bgp_ipv6_encap_tags_cmd, | |
553 | "show bgp ipv6 encap tags", | |
554 | SHOW_STR | |
555 | BGP_STR | |
556 | "Address Family\n" | |
557 | "Display ENCAP NLRI specific information\n" | |
558 | "Display BGP tags for prefixes\n") | |
559 | { | |
560 | return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL, 1); | |
561 | } | |
562 | #endif | |
563 | ||
564 | DEFUN (show_bgp_ipv4_encap_rd_tags, | |
565 | show_bgp_ipv4_encap_rd_tags_cmd, | |
566 | "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn tags", | |
567 | SHOW_STR | |
568 | BGP_STR | |
569 | "Address Family\n" | |
570 | "Display ENCAP NLRI specific information\n" | |
571 | "Display information for a route distinguisher\n" | |
572 | "ENCAP Route Distinguisher\n" | |
573 | "Display BGP tags for prefixes\n") | |
574 | { | |
575 | int ret; | |
576 | struct prefix_rd prd; | |
577 | ||
578 | ret = str2prefix_rd (argv[0], &prd); | |
579 | if (! ret) | |
580 | { | |
581 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
582 | return CMD_WARNING; | |
583 | } | |
584 | return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 1); | |
585 | } | |
586 | #ifdef HAVE_IPV6 | |
587 | DEFUN (show_bgp_ipv6_encap_rd_tags, | |
588 | show_bgp_ipv6_encap_rd_tags_cmd, | |
589 | "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn tags", | |
590 | SHOW_STR | |
591 | BGP_STR | |
592 | "Address Family\n" | |
593 | "Display ENCAP NLRI specific information\n" | |
594 | "Display information for a route distinguisher\n" | |
595 | "ENCAP Route Distinguisher\n" | |
596 | "Display BGP tags for prefixes\n") | |
597 | { | |
598 | int ret; | |
599 | struct prefix_rd prd; | |
600 | ||
601 | ret = str2prefix_rd (argv[0], &prd); | |
602 | if (! ret) | |
603 | { | |
604 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
605 | return CMD_WARNING; | |
606 | } | |
607 | return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 1); | |
608 | } | |
609 | #endif | |
610 | ||
611 | DEFUN (show_bgp_ipv4_encap_neighbor_routes, | |
612 | show_bgp_ipv4_encap_neighbor_routes_cmd, | |
613 | "show bgp ipv4 encap neighbors A.B.C.D routes", | |
614 | SHOW_STR | |
615 | BGP_STR | |
616 | "Address Family\n" | |
617 | "Display ENCAP NLRI specific information\n" | |
618 | "Detailed information on TCP and BGP neighbor connections\n" | |
619 | "Neighbor to display information about\n" | |
620 | "Display routes learned from neighbor\n") | |
621 | { | |
b6175e0c | 622 | union sockunion su; |
587ff0fd | 623 | struct peer *peer; |
b6175e0c CF |
624 | |
625 | if (str2sockunion(argv[0], &su)) | |
587ff0fd LB |
626 | { |
627 | vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); | |
628 | return CMD_WARNING; | |
629 | } | |
630 | ||
b6175e0c | 631 | peer = peer_lookup (NULL, &su); |
587ff0fd LB |
632 | if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP]) |
633 | { | |
634 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
635 | return CMD_WARNING; | |
636 | } | |
637 | ||
b6175e0c | 638 | return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_neighbor, &su, 0); |
587ff0fd LB |
639 | } |
640 | #ifdef HAVE_IPV6 | |
641 | DEFUN (show_bgp_ipv6_encap_neighbor_routes, | |
642 | show_bgp_ipv6_encap_neighbor_routes_cmd, | |
643 | "show bgp ipv6 encap neighbors A.B.C.D routes", | |
644 | SHOW_STR | |
645 | BGP_STR | |
646 | "Address Family\n" | |
647 | "Display ENCAP NLRI specific information\n" | |
648 | "Detailed information on TCP and BGP neighbor connections\n" | |
649 | "Neighbor to display information about\n" | |
650 | "Display routes learned from neighbor\n") | |
651 | { | |
b6175e0c | 652 | union sockunion su; |
587ff0fd LB |
653 | struct peer *peer; |
654 | ||
b6175e0c | 655 | if (str2sockunion(argv[0], &su)) |
587ff0fd LB |
656 | { |
657 | vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); | |
658 | return CMD_WARNING; | |
659 | } | |
660 | ||
b6175e0c | 661 | peer = peer_lookup (NULL, &su); |
587ff0fd LB |
662 | if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP]) |
663 | { | |
664 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
665 | return CMD_WARNING; | |
666 | } | |
667 | ||
b6175e0c | 668 | return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_neighbor, &su, 0); |
587ff0fd LB |
669 | } |
670 | #endif | |
671 | ||
672 | DEFUN (show_bgp_ipv4_encap_rd_neighbor_routes, | |
673 | show_bgp_ipv4_encap_rd_neighbor_routes_cmd, | |
674 | "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) routes", | |
675 | SHOW_STR | |
676 | BGP_STR | |
677 | "Address Family\n" | |
678 | "Display ENCAP NLRI specific information\n" | |
679 | "Display information for a route distinguisher\n" | |
680 | "ENCAP Route Distinguisher\n" | |
681 | "Detailed information on TCP and BGP neighbor connections\n" | |
682 | "Neighbor to display information about\n" | |
683 | "Neighbor to display information about\n" | |
684 | "Display routes learned from neighbor\n") | |
685 | { | |
686 | int ret; | |
b6175e0c | 687 | union sockunion su; |
587ff0fd LB |
688 | struct peer *peer; |
689 | struct prefix_rd prd; | |
690 | ||
691 | ret = str2prefix_rd (argv[0], &prd); | |
692 | if (! ret) | |
693 | { | |
694 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
695 | return CMD_WARNING; | |
696 | } | |
697 | ||
b6175e0c | 698 | if (str2sockunion(argv[1], &su)) |
587ff0fd LB |
699 | { |
700 | vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE); | |
701 | return CMD_WARNING; | |
702 | } | |
703 | ||
b6175e0c | 704 | peer = peer_lookup (NULL, &su); |
587ff0fd LB |
705 | if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP]) |
706 | { | |
707 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
708 | return CMD_WARNING; | |
709 | } | |
710 | ||
b6175e0c | 711 | return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_neighbor, &su, 0); |
587ff0fd LB |
712 | } |
713 | #ifdef HAVE_IPV6 | |
714 | DEFUN (show_bgp_ipv6_encap_rd_neighbor_routes, | |
715 | show_bgp_ipv6_encap_rd_neighbor_routes_cmd, | |
716 | "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) routes", | |
717 | SHOW_STR | |
718 | BGP_STR | |
719 | "Address Family\n" | |
720 | "Display ENCAP NLRI specific information\n" | |
721 | "Display information for a route distinguisher\n" | |
722 | "ENCAP Route Distinguisher\n" | |
723 | "Detailed information on TCP and BGP neighbor connections\n" | |
724 | "Neighbor to display information about\n" | |
725 | "Neighbor to display information about\n" | |
726 | "Display routes learned from neighbor\n") | |
727 | { | |
728 | int ret; | |
b6175e0c | 729 | union sockunion su; |
587ff0fd LB |
730 | struct peer *peer; |
731 | struct prefix_rd prd; | |
732 | ||
733 | ret = str2prefix_rd (argv[0], &prd); | |
734 | if (! ret) | |
735 | { | |
736 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
737 | return CMD_WARNING; | |
738 | } | |
739 | ||
b6175e0c | 740 | if (str2sockunion(argv[1], &su)) |
587ff0fd LB |
741 | { |
742 | vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE); | |
743 | return CMD_WARNING; | |
744 | } | |
745 | ||
b6175e0c | 746 | peer = peer_lookup (NULL, &su); |
587ff0fd LB |
747 | if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP]) |
748 | { | |
749 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
750 | return CMD_WARNING; | |
751 | } | |
752 | ||
b6175e0c | 753 | return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_neighbor, &su, 0); |
587ff0fd LB |
754 | } |
755 | #endif | |
756 | ||
757 | DEFUN (show_bgp_ipv4_encap_neighbor_advertised_routes, | |
758 | show_bgp_ipv4_encap_neighbor_advertised_routes_cmd, | |
759 | "show bgp ipv4 encap neighbors A.B.C.D advertised-routes", | |
760 | SHOW_STR | |
761 | BGP_STR | |
762 | "Address Family\n" | |
763 | "Display ENCAP NLRI specific information\n" | |
764 | "Detailed information on TCP and BGP neighbor connections\n" | |
765 | "Neighbor to display information about\n" | |
766 | "Display the routes advertised to a BGP neighbor\n") | |
767 | { | |
768 | int ret; | |
769 | struct peer *peer; | |
770 | union sockunion su; | |
771 | ||
772 | ret = str2sockunion (argv[0], &su); | |
773 | if (ret < 0) | |
774 | { | |
775 | vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE); | |
776 | return CMD_WARNING; | |
777 | } | |
778 | peer = peer_lookup (NULL, &su); | |
779 | if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP]) | |
780 | { | |
781 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
782 | return CMD_WARNING; | |
783 | } | |
784 | ||
785 | return show_adj_route_encap (vty, peer, NULL); | |
786 | } | |
787 | #ifdef HAVE_IPV6 | |
788 | DEFUN (show_bgp_ipv6_encap_neighbor_advertised_routes, | |
789 | show_bgp_ipv6_encap_neighbor_advertised_routes_cmd, | |
790 | "show bgp ipv6 encap neighbors A.B.C.D advertised-routes", | |
791 | SHOW_STR | |
792 | BGP_STR | |
793 | "Address Family\n" | |
794 | "Display ENCAP NLRI specific information\n" | |
795 | "Detailed information on TCP and BGP neighbor connections\n" | |
796 | "Neighbor to display information about\n" | |
797 | "Display the routes advertised to a BGP neighbor\n") | |
798 | { | |
799 | int ret; | |
800 | struct peer *peer; | |
801 | union sockunion su; | |
802 | ||
803 | ret = str2sockunion (argv[0], &su); | |
804 | if (ret < 0) | |
805 | { | |
806 | vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE); | |
807 | return CMD_WARNING; | |
808 | } | |
809 | peer = peer_lookup (NULL, &su); | |
810 | if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP]) | |
811 | { | |
812 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
813 | return CMD_WARNING; | |
814 | } | |
815 | ||
816 | return show_adj_route_encap (vty, peer, NULL); | |
817 | } | |
818 | #endif | |
819 | ||
820 | DEFUN (show_bgp_ipv4_encap_rd_neighbor_advertised_routes, | |
821 | show_bgp_ipv4_encap_rd_neighbor_advertised_routes_cmd, | |
822 | "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) advertised-routes", | |
823 | SHOW_STR | |
824 | BGP_STR | |
825 | "Address Family\n" | |
826 | "Display ENCAP NLRI specific information\n" | |
827 | "Display information for a route distinguisher\n" | |
828 | "ENCAP Route Distinguisher\n" | |
829 | "Detailed information on TCP and BGP neighbor connections\n" | |
830 | "Neighbor to display information about\n" | |
831 | "Neighbor to display information about\n" | |
832 | "Display the routes advertised to a BGP neighbor\n") | |
833 | { | |
834 | int ret; | |
835 | struct peer *peer; | |
836 | struct prefix_rd prd; | |
837 | union sockunion su; | |
838 | ||
839 | ret = str2sockunion (argv[1], &su); | |
840 | if (ret < 0) | |
841 | { | |
842 | vty_out (vty, "%% Malformed address: %s%s", argv[1], VTY_NEWLINE); | |
843 | return CMD_WARNING; | |
844 | } | |
845 | peer = peer_lookup (NULL, &su); | |
846 | if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP]) | |
847 | { | |
848 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
849 | return CMD_WARNING; | |
850 | } | |
851 | ||
852 | ret = str2prefix_rd (argv[0], &prd); | |
853 | if (! ret) | |
854 | { | |
855 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
856 | return CMD_WARNING; | |
857 | } | |
858 | ||
859 | return show_adj_route_encap (vty, peer, &prd); | |
860 | } | |
861 | #ifdef HAVE_IPV6 | |
862 | DEFUN (show_bgp_ipv6_encap_rd_neighbor_advertised_routes, | |
863 | show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd, | |
864 | "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) advertised-routes", | |
865 | SHOW_STR | |
866 | BGP_STR | |
867 | "Address Family\n" | |
868 | "Display ENCAP NLRI specific information\n" | |
869 | "Display information for a route distinguisher\n" | |
870 | "ENCAP Route Distinguisher\n" | |
871 | "Detailed information on TCP and BGP neighbor connections\n" | |
872 | "Neighbor to display information about\n" | |
873 | "Neighbor to display information about\n" | |
874 | "Display the routes advertised to a BGP neighbor\n") | |
875 | { | |
876 | int ret; | |
877 | struct peer *peer; | |
878 | struct prefix_rd prd; | |
879 | union sockunion su; | |
880 | ||
881 | ret = str2sockunion (argv[1], &su); | |
882 | if (ret < 0) | |
883 | { | |
884 | vty_out (vty, "%% Malformed address: %s%s", argv[1], VTY_NEWLINE); | |
885 | return CMD_WARNING; | |
886 | } | |
887 | peer = peer_lookup (NULL, &su); | |
888 | if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP]) | |
889 | { | |
890 | vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); | |
891 | return CMD_WARNING; | |
892 | } | |
893 | ||
894 | ret = str2prefix_rd (argv[0], &prd); | |
895 | if (! ret) | |
896 | { | |
897 | vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); | |
898 | return CMD_WARNING; | |
899 | } | |
900 | ||
901 | return show_adj_route_encap (vty, peer, &prd); | |
902 | } | |
903 | #endif | |
904 | ||
905 | void | |
906 | bgp_encap_init (void) | |
907 | { | |
8b1fb8be LB |
908 | install_element (BGP_ENCAP_NODE, &encap_network_cmd); |
909 | install_element (BGP_ENCAP_NODE, &no_encap_network_cmd); | |
587ff0fd LB |
910 | |
911 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_cmd); | |
912 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_cmd); | |
913 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_tags_cmd); | |
914 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_tags_cmd); | |
915 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_neighbor_routes_cmd); | |
916 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_neighbor_routes_cmd); | |
917 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_neighbor_advertised_routes_cmd); | |
918 | install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_neighbor_advertised_routes_cmd); | |
919 | ||
920 | #ifdef HAVE_IPV6 | |
921 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_cmd); | |
922 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_cmd); | |
923 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_tags_cmd); | |
924 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_tags_cmd); | |
925 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_neighbor_routes_cmd); | |
926 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_neighbor_routes_cmd); | |
927 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_neighbor_advertised_routes_cmd); | |
928 | install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd); | |
929 | #endif | |
587ff0fd | 930 | } |