📄 bgp_nexthop.c
字号:
u_char nexthop_num; struct nexthop *nexthop; struct bgp_nexthop_cache *bnc; s = zlookup->ibuf; stream_reset (s); nbytes = stream_read (s, zlookup->sock, 2); length = stream_getw (s); nbytes = stream_read (s, zlookup->sock, length - 2); command = stream_getc (s); stream_get (&raddr, s, 16); metric = stream_getl (s); nexthop_num = stream_getc (s); if (nexthop_num) { bnc = bnc_new (); bnc->valid = 1; bnc->metric = metric; bnc->nexthop_num = nexthop_num; for (i = 0; i < nexthop_num; i++) { nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop)); memset (nexthop, 0, sizeof (struct nexthop)); nexthop->type = stream_getc (s); switch (nexthop->type) { case ZEBRA_NEXTHOP_IPV6: stream_get (&nexthop->gate.ipv6, s, 16); break; case ZEBRA_NEXTHOP_IPV6_IFINDEX: case ZEBRA_NEXTHOP_IPV6_IFNAME: stream_get (&nexthop->gate.ipv6, s, 16); nexthop->ifindex = stream_getl (s); break; case ZEBRA_NEXTHOP_IFINDEX: case ZEBRA_NEXTHOP_IFNAME: nexthop->ifindex = stream_getl (s); break; } bnc_nexthop_add (bnc, nexthop); } } else return NULL; return bnc;}struct bgp_nexthop_cache *zlookup_query_ipv6 (struct in6_addr *addr){ int ret; struct stream *s; /* Check socket. */ if (zlookup->sock < 0) return NULL; s = zlookup->obuf; stream_reset (s); stream_putw (s, 19); stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP); stream_put (s, addr, 16); ret = writen (zlookup->sock, s->data, 19); if (ret < 0) { zlog_err ("can't write to zlookup->sock"); close (zlookup->sock); zlookup->sock = -1; return NULL; } if (ret == 0) { zlog_err ("zlookup->sock connection closed"); close (zlookup->sock); zlookup->sock = -1; return NULL; } return zlookup_read_ipv6 ();}#endif /* HAVE_IPV6 */intbgp_import_check (struct prefix *p, u_int32_t *igpmetric, struct in_addr *igpnexthop){ struct stream *s; int ret; u_int16_t length; u_char command; int nbytes; struct in_addr addr; struct in_addr nexthop; u_int32_t metric = 0; u_char nexthop_num; u_char nexthop_type; /* If lookup connection is not available return valid. */ if (zlookup->sock < 0) { if (igpmetric) *igpmetric = 0; return 1; } /* Send query to the lookup connection */ s = zlookup->obuf; stream_reset (s); stream_putw (s, 8); stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP); stream_putc (s, p->prefixlen); stream_put_in_addr (s, &p->u.prefix4); /* Write the packet. */ ret = writen (zlookup->sock, s->data, 8); if (ret < 0) { zlog_err ("can't write to zlookup->sock"); close (zlookup->sock); zlookup->sock = -1; return 1; } if (ret == 0) { zlog_err ("zlookup->sock connection closed"); close (zlookup->sock); zlookup->sock = -1; return 1; } /* Get result. */ stream_reset (s); /* Fetch length. */ nbytes = stream_read (s, zlookup->sock, 2); length = stream_getw (s); /* Fetch whole data. */ nbytes = stream_read (s, zlookup->sock, length - 2); command = stream_getc (s); addr.s_addr = stream_get_ipv4 (s); metric = stream_getl (s); nexthop_num = stream_getc (s); /* Set IGP metric value. */ if (igpmetric) *igpmetric = metric; /* If there is nexthop then this is active route. */ if (nexthop_num) { nexthop.s_addr = 0; nexthop_type = stream_getc (s); if (nexthop_type == ZEBRA_NEXTHOP_IPV4) { nexthop.s_addr = stream_get_ipv4 (s); if (igpnexthop) *igpnexthop = nexthop; } else *igpnexthop = nexthop; return 1; } else return 0;}/* Scan all configured BGP route then check the route exists in IGP or not. */intbgp_import (struct thread *t){ struct bgp_master *bm; struct bgp *bgp; struct bgp_node *rn; struct bgp_static *bgp_static; struct listnode *nn; int valid; u_int32_t metric; struct in_addr nexthop; afi_t afi; safi_t safi; bgp_import_thread = thread_add_timer (master, bgp_import, NULL, bgp_import_interval); bm = bgp_get_master (); if (! bm) return 0; LIST_LOOP (bm->bgp, bgp, nn) { for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST; safi < SAFI_MPLS_VPN; safi++) for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn)) if ((bgp_static = rn->info) != NULL) { if (bgp_static->backdoor) continue; valid = bgp_static->valid; metric = bgp_static->igpmetric; nexthop = bgp_static->igpnexthop; if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK) && afi == AFI_IP && safi == SAFI_UNICAST) bgp_static->valid = bgp_import_check (&rn->p, &bgp_static->igpmetric, &bgp_static->igpnexthop); else { bgp_static->valid = 1; bgp_static->igpmetric = 0; bgp_static->igpnexthop.s_addr = 0; } if (bgp_static->valid != valid) { if (bgp_static->valid) bgp_static_update (bgp, &rn->p, bgp_static, afi, safi); else bgp_static_withdraw (bgp, &rn->p, afi, safi); } else if (bgp_static->valid) { if (bgp_static->igpmetric != metric || bgp_static->igpnexthop.s_addr != nexthop.s_addr || bgp_static->rmap.name) bgp_static_update (bgp, &rn->p, bgp_static, afi, safi); } } } return 0;}/* Connect to zebra for nexthop lookup. */intzlookup_connect (struct thread *t){ struct zclient *zlookup; zlookup = THREAD_ARG (t); zlookup->t_connect = NULL; if (zlookup->sock != -1) return 0;#ifdef HAVE_TCP_ZEBRA zlookup->sock = zclient_socket ();#else zlookup->sock = zclient_socket_un (ZEBRA_SERV_PATH);#endif /* HAVE_TCP_ZEBRA */ if (zlookup->sock < 0) return -1; return 0;}/* Check specified multiaccess next-hop. */intbgp_multiaccess_check_v4 (struct in_addr nexthop, char *peer){ struct bgp_node *rn1; struct bgp_node *rn2; struct prefix p1; struct prefix p2; struct in_addr addr; int ret; ret = inet_aton (peer, &addr); if (! ret) return 0; memset (&p1, 0, sizeof (struct prefix)); p1.family = AF_INET; p1.prefixlen = IPV4_MAX_BITLEN; p1.u.prefix4 = nexthop; memset (&p2, 0, sizeof (struct prefix)); p2.family = AF_INET; p2.prefixlen = IPV4_MAX_BITLEN; p2.u.prefix4 = addr; /* If bgp scan is not enabled, return invalid. */ if (zlookup->sock < 0) return 0; rn1 = bgp_node_match (bgp_connected_ipv4, &p1); if (! rn1) return 0; rn2 = bgp_node_match (bgp_connected_ipv4, &p2); if (! rn2) return 0; if (rn1 == rn2) return 1; return 0;}DEFUN (bgp_scan_time, bgp_scan_time_cmd, "bgp scan-time <5-60>", "BGP specific commands\n" "Configure background scanner interval\n" "Scanner interval (seconds)\n"){ bgp_scan_interval = atoi (argv[0]); if (bgp_scan_thread) { thread_cancel (bgp_scan_thread); bgp_scan_thread = thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval); } return CMD_SUCCESS;}DEFUN (no_bgp_scan_time, no_bgp_scan_time_cmd, "no bgp scan-time", NO_STR "BGP specific commands\n" "Configure background scanner interval\n"){ bgp_scan_interval = BGP_SCAN_INTERVAL_DEFAULT; if (bgp_scan_thread) { thread_cancel (bgp_scan_thread); bgp_scan_thread = thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval); } return CMD_SUCCESS;}ALIAS (no_bgp_scan_time, no_bgp_scan_time_val_cmd, "no bgp scan-time <5-60>", NO_STR "BGP specific commands\n" "Configure background scanner interval\n" "Scanner interval (seconds)\n");DEFUN (show_ip_bgp_scan, show_ip_bgp_scan_cmd, "show ip bgp scan", SHOW_STR IP_STR BGP_STR "BGP scan status\n"){ struct bgp_node *rn; struct bgp_nexthop_cache *bnc; if (bgp_scan_thread) vty_out (vty, "BGP scan is running%s", VTY_NEWLINE); else vty_out (vty, "BGP scan is not running%s", VTY_NEWLINE); vty_out (vty, "BGP scan interval is %d%s", bgp_scan_interval, VTY_NEWLINE); vty_out (vty, "Current BGP nexthop cache:%s", VTY_NEWLINE); for (rn = bgp_table_top (bgp_nexthop_cache_ipv4); rn; rn = bgp_route_next (rn)) if ((bnc = rn->info) != NULL) { if (bnc->valid) vty_out (vty, " %s valid [IGP metric %d]%s", inet_ntoa (rn->p.u.prefix4), bnc->metric, VTY_NEWLINE); else vty_out (vty, " %s invalid%s", inet_ntoa (rn->p.u.prefix4), VTY_NEWLINE); }#ifdef HAVE_IPV6 { char buf[BUFSIZ]; for (rn = bgp_table_top (bgp_nexthop_cache_ipv6); rn; rn = bgp_route_next (rn)) if ((bnc = rn->info) != NULL) { if (bnc->valid) vty_out (vty, " %s valid [IGP metric %d]%s", inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ), bnc->metric, VTY_NEWLINE); else vty_out (vty, " %s invalid%s", inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ), VTY_NEWLINE); } }#endif /* HAVE_IPV6 */ vty_out (vty, "BGP connected route:%s", VTY_NEWLINE); for (rn = bgp_table_top (bgp_connected_ipv4); rn; rn = bgp_route_next (rn)) if (rn->info != NULL) vty_out (vty, " %s/%d%s", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen, VTY_NEWLINE);#ifdef HAVE_IPV6 { char buf[BUFSIZ]; for (rn = bgp_table_top (bgp_connected_ipv6); rn; rn = bgp_route_next (rn)) if (rn->info != NULL) vty_out (vty, " %s/%d%s", inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ), rn->p.prefixlen, VTY_NEWLINE); }#endif /* HAVE_IPV6 */ return CMD_SUCCESS;}intbgp_config_write_scan_time (struct vty *vty){ if (bgp_scan_interval != BGP_SCAN_INTERVAL_DEFAULT) vty_out (vty, " bgp scan-time %d%s", bgp_scan_interval, VTY_NEWLINE); return CMD_SUCCESS;}voidbgp_scan_init (){ zlookup = zclient_new (); zlookup->sock = -1; zlookup->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ); zlookup->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ); zlookup->t_connect = thread_add_event (master, zlookup_connect, zlookup, 0); bgp_scan_interval = BGP_SCAN_INTERVAL_DEFAULT; bgp_import_interval = BGP_IMPORT_INTERVAL_DEFAULT; cache1 = bgp_table_init (); cache2 = bgp_table_init (); bgp_nexthop_cache_ipv4 = cache1; bgp_connected_ipv4 = bgp_table_init ();#ifdef HAVE_IPV6 cache6_1 = bgp_table_init (); cache6_2 = bgp_table_init (); bgp_nexthop_cache_ipv6 = cache6_1; bgp_connected_ipv6 = bgp_table_init ();#endif /* HAVE_IPV6 */ /* Make BGP scan thread. */ bgp_scan_thread = thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval); /* Make BGP import there. */ bgp_import_thread = thread_add_timer (master, bgp_import, NULL, 0); install_element (BGP_NODE, &bgp_scan_time_cmd); install_element (BGP_NODE, &no_bgp_scan_time_cmd); install_element (BGP_NODE, &no_bgp_scan_time_val_cmd); install_element (VIEW_NODE, &show_ip_bgp_scan_cmd); install_element (ENABLE_NODE, &show_ip_bgp_scan_cmd);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -