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