📄 bgp_route.c
字号:
struct bgp_adj_out *aout; struct bgp_info *ri; if (! table) table = peer->bgp->rib[afi][safi]; for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) { for (ri = rn->info; ri; ri = ri->next) if (ri->peer == peer) { bgp_rib_remove (rn, ri, peer, afi, safi); break; } for (ain = rn->adj_in; ain; ain = ain->next) if (ain->peer == peer) { bgp_adj_in_remove (rn, ain); bgp_unlock_node (rn); break; } for (aout = rn->adj_out; aout; aout = aout->next) if (aout->peer == peer) { bgp_adj_out_remove (rn, aout, peer, afi, safi); bgp_unlock_node (rn); break; } }}voidbgp_clear_route (struct peer *peer, afi_t afi, safi_t safi){ struct bgp_node *rn; struct bgp_table *table; if (! peer->afc[afi][safi]) return; if (safi != SAFI_MPLS_VPN) bgp_clear_route_table (peer, afi, safi, NULL); else for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn; rn = bgp_route_next (rn)) if ((table = rn->info) != NULL) bgp_clear_route_table (peer, afi, safi, table);} voidbgp_clear_route_all (struct peer *peer){ afi_t afi; safi_t safi; for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) bgp_clear_route (peer, afi, safi);}voidbgp_clear_adj_in (struct peer *peer, afi_t afi, safi_t safi){ struct bgp_table *table; struct bgp_node *rn; struct bgp_adj_in *ain; table = peer->bgp->rib[afi][safi]; for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) for (ain = rn->adj_in; ain ; ain = ain->next) if (ain->peer == peer) { bgp_adj_in_remove (rn, ain); bgp_unlock_node (rn); break; }}/* Delete all kernel routes. */voidbgp_terminate (){ struct bgp *bgp; struct listnode *nn; struct bgp_node *rn; struct bgp_table *table; struct bgp_info *ri; LIST_LOOP (bm->bgp, bgp, nn) { table = bgp->rib[AFI_IP][SAFI_UNICAST]; for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) for (ri = rn->info; ri; ri = ri->next) if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED) && ri->type == ZEBRA_ROUTE_BGP && ri->sub_type == BGP_ROUTE_NORMAL) bgp_zebra_withdraw (&rn->p, ri); table = bgp->rib[AFI_IP6][SAFI_UNICAST]; for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) for (ri = rn->info; ri; ri = ri->next) if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED) && ri->type == ZEBRA_ROUTE_BGP && ri->sub_type == BGP_ROUTE_NORMAL) bgp_zebra_withdraw (&rn->p, ri); }}voidbgp_reset (){ vty_reset (); bgp_zclient_reset (); access_list_reset (); prefix_list_reset ();}/* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr value. */intbgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet){ u_char *pnt; u_char *lim; struct prefix p; int psize; int ret; /* Check peer status. */ if (peer->status != Established) return 0; pnt = packet->nlri; lim = pnt + packet->length; for (; pnt < lim; pnt += psize) { /* Clear prefix structure. */ memset (&p, 0, sizeof (struct prefix)); /* Fetch prefix length. */ p.prefixlen = *pnt++; p.family = afi2family (packet->afi); /* Already checked in nlri_sanity_check(). We do double check here. */ if ((packet->afi == AFI_IP && p.prefixlen > 32) || (packet->afi == AFI_IP6 && p.prefixlen > 128)) return -1; /* Packet size overflow check. */ psize = PSIZE (p.prefixlen); /* When packet overflow occur return immediately. */ if (pnt + psize > lim) return -1; /* Fetch prefix from NLRI packet. */ memcpy (&p.u.prefix, pnt, psize); /* Check address. */ if (packet->afi == AFI_IP && packet->safi == SAFI_UNICAST) { if (IN_CLASSD (ntohl (p.u.prefix4.s_addr))) { zlog (peer->log, LOG_ERR, "IPv4 unicast NLRI is multicast address %s", inet_ntoa (p.u.prefix4)); bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_INVAL_NETWORK); return -1; } }#ifdef HAVE_IPV6 /* Check address. */ if (packet->afi == AFI_IP6 && packet->safi == SAFI_UNICAST) { if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6)) { char buf[BUFSIZ]; zlog (peer->log, LOG_WARNING, "IPv6 link-local NLRI received %s ignore this NLRI", inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ)); continue; } }#endif /* HAVE_IPV6 */ /* Normal process. */ if (attr) ret = bgp_update (peer, &p, attr, packet->afi, packet->safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, 0); else ret = bgp_withdraw (peer, &p, attr, packet->afi, packet->safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL); /* Address family configuration mismatch or maximum-prefix count overflow. */ if (ret < 0) return -1; } /* Packet length consistency check. */ if (pnt != lim) return -1; return 0;}/* NLRI encode syntax check routine. */intbgp_nlri_sanity_check (struct peer *peer, int afi, u_char *pnt, bgp_size_t length){ u_char *end; u_char prefixlen; int psize; end = pnt + length; /* RFC1771 6.3 The NLRI field in the UPDATE message is checked for syntactic validity. If the field is syntactically incorrect, then the Error Subcode is set to Invalid Network Field. */ while (pnt < end) { prefixlen = *pnt++; /* Prefix length check. */ if ((afi == AFI_IP && prefixlen > 32) || (afi == AFI_IP6 && prefixlen > 128)) { plog_err (peer->log, "%s [Error] Update packet error (wrong prefix length %d)", peer->host, prefixlen); bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_INVAL_NETWORK); return -1; } /* Packet size overflow check. */ psize = PSIZE (prefixlen); if (pnt + psize > end) { plog_err (peer->log, "%s [Error] Update packet error" " (prefix data overflow prefix size is %d)", peer->host, psize); bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_INVAL_NETWORK); return -1; } pnt += psize; } /* Packet length consistency check. */ if (pnt != end) { plog_err (peer->log, "%s [Error] Update packet error" " (prefix length mismatch with total length)", peer->host); bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_INVAL_NETWORK); return -1; } return 0;}struct bgp_static *bgp_static_new (){ struct bgp_static *new; new = XMALLOC (MTYPE_BGP_STATIC, sizeof (struct bgp_static)); memset (new, 0, sizeof (struct bgp_static)); return new;}voidbgp_static_free (struct bgp_static *bgp_static){ if (bgp_static->rmap.name) free (bgp_static->rmap.name); XFREE (MTYPE_BGP_STATIC, bgp_static);}voidbgp_static_update (struct bgp *bgp, struct prefix *p, struct bgp_static *bgp_static, afi_t afi, safi_t safi){ struct bgp_node *rn; struct bgp_info *ri; struct bgp_info *new; struct bgp_info info; struct attr attr; struct attr attr_tmp; struct attr *attr_new; int ret; rn = bgp_afi_node_get (bgp, afi, safi, p, NULL); bgp_attr_default_set (&attr, BGP_ORIGIN_IGP); if (bgp_static) { attr.nexthop = bgp_static->igpnexthop; attr.med = bgp_static->igpmetric; attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); } /* Apply route-map. */ if (bgp_static->rmap.name) { attr_tmp = attr; info.peer = bgp->peer_self; info.attr = &attr_tmp; ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info); if (ret == RMAP_DENYMATCH) { /* Free uninterned attribute. */ bgp_attr_flush (&attr_tmp); /* Unintern original. */ aspath_unintern (attr.aspath); bgp_static_withdraw (bgp, p, afi, safi); return; } attr_new = bgp_attr_intern (&attr_tmp); } else attr_new = bgp_attr_intern (&attr); for (ri = rn->info; ri; ri = ri->next) if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP && ri->sub_type == BGP_ROUTE_STATIC) break; if (ri) { if (attrhash_cmp (ri->attr, attr_new)) { bgp_unlock_node (rn); bgp_attr_unintern (attr_new); aspath_unintern (attr.aspath); return; } else { /* The attribute is changed. */ SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED); /* Rewrite BGP route information. */ bgp_aggregate_decrement (bgp, p, ri, afi, safi); bgp_attr_unintern (ri->attr); ri->attr = attr_new; ri->uptime = time (NULL); /* Process change. */ bgp_aggregate_increment (bgp, p, ri, afi, safi); bgp_process (bgp, rn, afi, safi); bgp_unlock_node (rn); aspath_unintern (attr.aspath); return; } } /* Make new BGP info. */ new = bgp_info_new (); new->type = ZEBRA_ROUTE_BGP; new->sub_type = BGP_ROUTE_STATIC; new->peer = bgp->peer_self; SET_FLAG (new->flags, BGP_INFO_VALID); new->attr = attr_new; new->uptime = time (NULL); /* Aggregate address increment. */ bgp_aggregate_increment (bgp, p, new, afi, safi); /* Register new BGP information. */ bgp_info_add (rn, new); /* Process change. */ bgp_process (bgp, rn, afi, safi); /* Unintern original. */ aspath_unintern (attr.aspath);}voidbgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi, u_char safi, struct prefix_rd *prd, u_char *tag){ struct bgp_node *rn; struct bgp_info *new; rn = bgp_afi_node_get (bgp, afi, safi, p, prd); /* Make new BGP info. */ new = bgp_info_new (); new->type = ZEBRA_ROUTE_BGP; new->sub_type = BGP_ROUTE_STATIC; new->peer = bgp->peer_self; new->attr = bgp_attr_default_intern (BGP_ORIGIN_IGP); SET_FLAG (new->flags, BGP_INFO_VALID); new->uptime = time (NULL); memcpy (new->tag, tag, 3); /* Aggregate address increment. */ bgp_aggregate_increment (bgp, p, (struct bgp_info *) new, afi, safi); /* Register new BGP information. */ bgp_info_add (rn, (struct bgp_info *) new); /* Process change. */ bgp_process (bgp, rn, afi, safi);}voidbgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi){ struct bgp_node *rn; struct bgp_info *ri; rn = bgp_afi_node_get (bgp, afi, safi, p, NULL); /* Check selected route and self inserted route. */ for (ri = rn->info; ri; ri = ri->next) if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP && ri->sub_type == BGP_ROUTE_STATIC) break; /* Withdraw static BGP route from routing table. */ if (ri) { bgp_aggregate_decrement (bgp, p, ri, afi, safi); UNSET_FLAG (ri->flags, BGP_INFO_VALID); bgp_process (bgp, rn, afi, safi); bgp_info_delete (rn, ri); bgp_info_free (ri); bgp_unlock_node (rn); } /* Unlock bgp_node_lookup. */ bgp_unlock_node (rn);}voidbgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi, u_char safi, struct prefix_rd *prd, u_char *tag){ struct bgp_node *rn; struct bgp_info *ri; rn = bgp_afi_node_get (bgp, afi, safi, p, prd); /* Check selected route and self inserted route. */ for (ri = rn->info; ri; ri = ri->next) if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP && ri->sub_type == BGP_ROUTE_STATIC) break; /* Withdraw static BGP route from routing table. */ if (ri) { bgp_aggregate_decrement (bgp, p, ri, afi, safi); UNSET_FLAG (ri->flags, BGP_INFO_VALID); bgp_process (bgp, rn, afi, safi); bgp_info_delete (rn, ri); bgp_info_free (ri); bgp_unlock_node (rn); } /* Unlock bgp_node_lookup. */ bgp_unlock_node (rn);}/* Configure static BGP network. When user don't run zebra, static route should be installed as valid. */intbgp_static_set (struct vty *vty, struct bgp *bgp, char *ip_str, u_int16_t afi, u_char safi, char *rmap, int backdoor){ int ret; struct prefix p; struct bgp_static *bgp_static; struct bgp_node *rn; int need_update = 0; /* Convert IP prefix string to struct prefix. */ ret = str2prefix (ip_str, &p); if (! ret)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -