📄 bgpd.c
字号:
BGP_EVENT_ADD (peer, BGP_Start); } } else if (peer->status == Established) { if (flag == PEER_FLAG_DYNAMIC_CAPABILITY) peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK) peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE; if (flag != PEER_FLAG_CONNECT_MODE_ACTIVE && flag != PEER_FLAG_CONNECT_MODE_PASSIVE) bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else BGP_EVENT_ADD (peer, BGP_Stop);}/* Change specified peer flag. */intpeer_flag_modify (struct peer *peer, u_int32_t flag, int set){ int found; int size; struct peer_group *group; struct listnode *nn; struct peer_flag_action action; memset (&action, 0, sizeof (struct peer_flag_action)); size = sizeof peer_flag_action_list / sizeof (struct peer_flag_action); found = peer_flag_action_set (peer_flag_action_list, size, &action, flag); /* No flag action is found. */ if (! found) return BGP_ERR_INVALID_FLAG; /* Not for peer-group member. */ if (action.not_for_member && peer_group_member (peer)) return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; /* When unset the peer-group member's flag we have to check peer-group configuration. */ if (! set && peer_group_member (peer)) if (CHECK_FLAG (peer->group->conf->flags, flag)) { if (flag == PEER_FLAG_SHUTDOWN) return BGP_ERR_PEER_GROUP_SHUTDOWN; else return BGP_ERR_PEER_GROUP_HAS_THE_FLAG; } /* Flag conflict check. */ if (set && CHECK_FLAG (peer->flags | flag, PEER_FLAG_STRICT_CAP_MATCH) && CHECK_FLAG (peer->flags | flag, PEER_FLAG_OVERRIDE_CAPABILITY)) return BGP_ERR_PEER_FLAG_CONFLICT; if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { if (set && CHECK_FLAG (peer->flags, flag) == flag) return 0; if (! set && ! CHECK_FLAG (peer->flags, flag)) return 0; } if (set) SET_FLAG (peer->flags, flag); else UNSET_FLAG (peer->flags, flag); if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { if (action.type == peer_change_reset) peer_flag_modify_action (peer, flag); return 0; } /* peer-group member updates. */ group = peer->group; LIST_LOOP (group->peer, peer, nn) { if (set && CHECK_FLAG (peer->flags, flag) == flag) continue; if (! set && ! CHECK_FLAG (peer->flags, flag)) continue; if (set) SET_FLAG (peer->flags, flag); else UNSET_FLAG (peer->flags, flag); if (action.type == peer_change_reset) peer_flag_modify_action (peer, flag); } return 0;}intpeer_flag_set (struct peer *peer, u_int32_t flag){ return peer_flag_modify (peer, flag, 1);}intpeer_flag_unset (struct peer *peer, u_int32_t flag){ return peer_flag_modify (peer, flag, 0);}intpeer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag, int set){ int found; int size; struct listnode *nn; struct peer_group *group; struct peer_flag_action action; memset (&action, 0, sizeof (struct peer_flag_action)); size = sizeof peer_af_flag_action_list / sizeof (struct peer_flag_action); found = peer_flag_action_set (peer_af_flag_action_list, size, &action, flag); /* No flag action is found. */ if (! found) return BGP_ERR_INVALID_FLAG; /* Adress family must be activated. */ if (! peer->afc[afi][safi]) return BGP_ERR_PEER_INACTIVE; /* Not for peer-group member. */ if (action.not_for_member && peer_group_member (peer)) return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; /* Spcecial check for reflector client. */ if (flag & PEER_FLAG_REFLECTOR_CLIENT && peer_sort (peer) != BGP_PEER_IBGP) return BGP_ERR_NOT_INTERNAL_PEER; /* Spcecial check for remove-private-AS. */ if (flag & PEER_FLAG_REMOVE_PRIVATE_AS && peer_sort (peer) == BGP_PEER_IBGP) return BGP_ERR_REMOVE_PRIVATE_AS; /* When unset the peer-group member's flag we have to check peer-group configuration. */ if (! set && peer_group_member(peer)) if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi], flag)) return BGP_ERR_PEER_GROUP_HAS_THE_FLAG; /* When current flag configuration is same as requested one. */ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag) return 0; if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag)) return 0; } if (set) SET_FLAG (peer->af_flags[afi][safi], flag); else UNSET_FLAG (peer->af_flags[afi][safi], flag); /* Execute action when peer is established. */ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP) && peer->status == Established) { if (! set && flag == PEER_FLAG_SOFT_RECONFIG) bgp_clear_adj_in (peer, afi, safi); else { if (flag == PEER_FLAG_REFLECTOR_CLIENT) peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE; else if (flag == PEER_FLAG_RSERVER_CLIENT) peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE; else if (flag == PEER_FLAG_ORF_PREFIX_SM) peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; else if (flag == PEER_FLAG_ORF_PREFIX_RM) peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; peer_change_action (peer, afi, safi, action.type); } } /* Peer group member updates. */ if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { group = peer->group; LIST_LOOP (group->peer, peer, nn) { if (! peer->afc[afi][safi]) continue; if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag) continue; if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag)) continue; if (set) SET_FLAG (peer->af_flags[afi][safi], flag); else UNSET_FLAG (peer->af_flags[afi][safi], flag); if (peer->status == Established) { if (! set && flag == PEER_FLAG_SOFT_RECONFIG) bgp_clear_adj_in (peer, afi, safi); else { if (flag == PEER_FLAG_REFLECTOR_CLIENT) peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE; else if (flag == PEER_FLAG_RSERVER_CLIENT) peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE; else if (flag == PEER_FLAG_ORF_PREFIX_SM) peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; else if (flag == PEER_FLAG_ORF_PREFIX_RM) peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; peer_change_action (peer, afi, safi, action.type); } } } } return 0;}intpeer_af_flag_set (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag){ return peer_af_flag_modify (peer, afi, safi, flag, 1);}intpeer_af_flag_unset (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag){ return peer_af_flag_modify (peer, afi, safi, flag, 0);}/* EBGP multihop configuration. */intpeer_ebgp_multihop_set (struct peer *peer, int ttl){ struct peer_group *group; struct listnode *nn; if (peer_sort (peer) == BGP_PEER_IBGP) return 0; peer->ttl = ttl; if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP) sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl); } else { group = peer->group; LIST_LOOP (group->peer, peer, nn) { if (peer_sort (peer) == BGP_PEER_IBGP) continue; peer->ttl = group->conf->ttl; if (peer->fd >= 0) sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl); } } return 0;}intpeer_ebgp_multihop_unset (struct peer *peer){ struct peer_group *group; struct listnode *nn; if (peer_sort (peer) == BGP_PEER_IBGP) return 0; if (peer_group_member (peer)) peer->ttl = peer->group->conf->ttl; else peer->ttl = 1; if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP) sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl); } else { group = peer->group; LIST_LOOP (group->peer, peer, nn) { if (peer_sort (peer) == BGP_PEER_IBGP) continue; peer->ttl = 1; if (peer->fd >= 0) sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl); } } return 0;}/* Neighbor description. */intpeer_description_set (struct peer *peer, char *desc){ if (peer->desc) XFREE (MTYPE_PEER_DESC, peer->desc); peer->desc = XSTRDUP (MTYPE_PEER_DESC, desc); return 0;}intpeer_description_unset (struct peer *peer){ if (peer->desc) XFREE (MTYPE_PEER_DESC, peer->desc); peer->desc = NULL; return 0;}/* Neighbor update-source. */intpeer_update_source_if_set (struct peer *peer, char *ifname){ struct peer_group *group; struct listnode *nn; if (peer->update_if) { if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP) && strcmp (peer->update_if, ifname) == 0) return 0; XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); peer->update_if = NULL; } if (peer->update_source) { sockunion_free (peer->update_source); peer->update_source = NULL; } peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname); if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { if (peer->status == Established) { peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else BGP_EVENT_ADD (peer, BGP_Stop); return 0; } /* peer-group member updates. */ group = peer->group; LIST_LOOP (group->peer, peer, nn) { if (peer->update_if) { if (strcmp (peer->update_if, ifname) == 0) continue; XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); peer->update_if = NULL; } if (peer->update_source) { sockunion_free (peer->update_source); peer->update_source = NULL; } peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname); if (peer->status == Established) { peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else BGP_EVENT_ADD (peer, BGP_Stop); } return 0;}intpeer_update_source_addr_set (struct peer *peer, union sockunion *su){ struct peer_group *group; struct listnode *nn;#ifdef HAVE_OPENBSD_TCP_SIGNATURE if (peer->password) bgp_tcpsig_unset (bm->sock, peer);#endif /* HAVE_OPENBSD_TCP_SIGNATURE */ if (peer->update_source) { if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP) && sockunion_cmp (peer->update_source, su) == 0) return 0; sockunion_free (peer->update_source); peer->update_source = NULL; } if (peer->update_if) { XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); peer->update_if = NULL; }#ifdef HAVE_OPENBSD_TCP_SIGNATURE if (peer->password) bgp_tcpsig_set (bm->sock, peer);#endif /* HAVE_OPENBSD_TCP_SIGNATURE */ peer->update_source = sockunion_dup (su); if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { if (peer->status == Established) { peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else BGP_EVENT_ADD (peer, BGP_Stop); return 0; } /* peer-group member updates. */ group = peer->group; LIST_LOOP (group->peer, peer, nn) {#ifdef HAVE_OPENBSD_TCP_SIGNATURE if (peer->password) bgp_tcpsig_unset (bm->sock, peer);#endif /* HAVE_OPENBSD_TCP_SIGNATURE */ if (peer->update_source) { if (sockunion_cmp (peer->update_source, su) == 0) continue; sockunion_free (peer->update_source); peer->update_source = NULL; } if (peer->update_if) { XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); peer->update_if = NULL; } peer->update_source = sockunion_dup (su);#ifdef HAVE_OPENBSD_TCP_SIGNATURE if (peer->password) bgp_tcpsig_set (bm->sock, peer);#endif /* HAVE_OPENBSD_TCP_SIGNATURE */ if (peer->status == Established) { peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else BGP_EVENT_ADD (peer, BGP_Stop); } return 0;}intpeer_update_source_unset (struct peer *peer){ union sockunion *su; struct peer_group *group; struct listnode *nn; if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP) && ! peer->update_source && ! peer->update_if) return 0;#ifdef HAVE_OPENBSD_TCP_SIGNATURE if (peer->password) bgp_tcpsig_unset (bm->sock, peer);#endif /* HAVE_OPENBSD_TCP_SIGNATURE */ if (peer->update_source) { sockunion_free (peer->update_source); peer->update_source = NULL; } if (peer->update_if) { XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); peer->update_if = NULL; } if (peer_group_member (peer)) { group = peer->group; if (group->conf->update_source) { su = sockunion_dup (group->conf->update_source); peer->update_source = su; } else if (group->conf->update_if) peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, group->conf->update_if); } if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { if (peer->status =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -