/* * $Id: bgp.h,v 2.3 2000/06/08 04:00:45 masaki Exp $ */ #ifndef _BGP_H #define _BGP_H #include #include #include #include #include #include #include #include struct _bgp_attr_t; #define bgp_attr_t struct _bgp_attr_t /* various settable attributes */ #define DEFAULT_PEER_NAME "glasshouse.merit.edu" #define DEFAULT_PEER_AS 185 #ifdef notdef #define DEFAULT_MY_AS 6503 #define DEFAULT_MY_ID 0xc66c3cb0 #endif #define DEFAULT_LOCAL_AS 6503 #define DEFAULT_ROUTER_ID 0xc66c3cb0 #define MAX_AS_NUMBER 65535 #define DEFAULT_DATAFILE "/tmp/bgp.data" #define DEFAULT_BGP_VERSION 4 #define DEFAULT_BGP4PLUS_VERSION 1 /* 0, 1, 2 -- auto */ #define DEFAULT_CONNET_RETRY_INTERVAL 120 /* was 60 */ #define DEFAULT_START_INTERVAL 10 /* RFC suggests 60 */ #define DEFAULT_KEEPALIVE_INTERVAL 30 #define DEFAULT_HOLDTIME_INTERVAL 90 /* was 180 */ #define BGP_OPEN_TIMEOUT 240 #define BGP_MIN_HOLDTIME 20 /* What we'll accept */ /* pdu types */ #define BGP_OPEN 1 #define BGP_UPDATE 2 #define BGP_NOTIFICATION 3 #define BGP_KEEPALIVE 4 /* saving routing table to disk (mrtd) */ #define DUMP_ASCII 1 #define DUMP_BINARY 2 #define DUMP_DIR_RECV 0x01 #define DUMP_DIR_SEND 0x02 #define DUMP_DIR_BOTH (DUMP_DIR_RECV|DUMP_DIR_SEND) extern char *sbgp_states[]; extern char *sbgp_pdus[]; extern char *sbgp_events[]; extern char *s_bgp_error[]; extern char *s_bgp_error_header[]; extern char *s_bgp_error_open[]; extern char *s_bgp_error_update[]; #define BGP_TRANSPARENT_AS 0x00001 #define BGP_TRANSPARENT_NEXTHOP 0x00002 #define BGP_CONNECT_PASSIVE 0x00004 /* don't try to connect */ #define BGP_BGP4PLUS_00_RCVD 0x00008 #define BGP_BGP4PLUS_00 0x00010 /* draft 00 */ #define BGP_BGP4PLUS_01 0x00020 /* draft 01 */ #define BGP_BGP4PLUS_AUTO 0x00040 /* auto detection */ #define BGP_BGP4PLUS_01_RCVD 0x00080 /* no fall-back */ #define BGP_BGP4PLUS_DEFAULT (BGP_BGP4PLUS_AUTO|BGP_BGP4PLUS_01) /* default is now "auto" */ #define BGP_EBGP_MULTIHOP 0x00100 #define BGP_NEXTHOP_SELF 0x00200 #define BGP_INTERNAL 0x00400 #define BGP_ROUTE_REFLECTOR_CLIENT 0x00800 #define BGP_DONTSEND_CAPABILITY 0x01000 #define BGP_REMOVE_PRIVATE_AS 0x02000 #define BGP_NEXTHOP_PEER 0x04000 #define BGP_PEER_CISCO 0x08000 #define BGP_PEER_TEST 0x10000 #define BGP_PEER_SELF 0x20000 /* on the same host */ typedef struct listen_socket_t { int sockfd; int ref_count; prefix_t *prefix; interface_t *interface; pthread_mutex_t mutex_lock; LINKED_LIST *ll_accept_sockets; } listen_socket_t; typedef struct accept_socket_t { int sockfd; u_char buffer_in[BGPMAXPACKETSIZE]; u_char *read_ptr_in; /* current ptr of read in buffer */ time_t start_time; listen_socket_t *listen_socket; prefix_t *remote_prefix; prefix_t *local_prefix; int remote_port; } accept_socket_t; typedef struct _bgp_bitset_t { bitx_mask_t bits[(MAX_BGP_PEERS+BITX_NBITS-1)/BITX_NBITS]; } bgp_bitset_t; typedef struct _bgp_local_t { int this_as; #if 0 int cport; /* port to send out open on */ int lport; /* port to listen for open on */ #endif trace_t *trace; /* must fix ID stuff when adding interface things. Currently everything gets the same router_id which is unnacceptable. -- binkertn */ u_long this_id; u_long cluster_id; pthread_mutex_t mutex_lock; /* LINKED_LIST *ll_views; */ bgp_bitset_t view_mask; bgp_bitset_t bits_assigned; /* record the peers' bits */ pthread_mutex_t peers_mutex_lock; /* a lock for ll_bgp_peers */ LINKED_LIST *ll_bgp_peers; int num_peers; /* number of peers */ int num_ipv4_peers; /* number of IPv4 peers */ int bind_interface_only; int num_interfaces; LINKED_LIST *ll_interfaces; } bgp_local_t; typedef struct _bgp_filters_t { int dlist_in; /* list num for input filtering */ int dlist_out; /* list num for output filtering */ int flist_in; /* list num for input aspath filtering */ int flist_out; /* list num for output aspath filtering */ int clist_in; /* list num for input community filtering */ int clist_out; /* list num for output community filtering */ int route_map_in; /* num for input route-map */ int route_map_out; /* num for output route-map */ } bgp_filters_t; typedef struct _bgp_peer_t { char *name; char *description; interface_t *bind_if; prefix_t *bind_addr; /* the following may be duplicated in gateway, but these are ones specified by the user */ prefix_t *peer_addr; /* peer address only */ int peer_as; /* peer's as number */ u_long peer_id; /* peer's router id */ int peer_port; /* port number in case it isn't 179 */ gateway_t *gateway; interface_t *interface; /* interface once seen (for information) */ prefix_t *local_addr; /* local address for the peer */ nexthop_t *nexthop; /* immediate next hop */ int new_as; /* this will be used at the next start */ int new_id; /* this will be used at the next start */ LINKED_LIST *aliases; /* peer's aliases */ int sockfd; /* sockect connected to peer */ listen_socket_t *listen_socket; /* sockect for listening incoming connection */ u_long index; /* index (used by view in mask) */ u_long options; /* see options above */ bgp_local_t *local_bgp; /* local bgp session */ int neighbor_list; /* if > 0, this is a neighbor list */ LINKED_LIST *children; struct _bgp_peer_t *parent; bgp_bitset_t view_mask; /* which views routes being injected */ pthread_mutex_t mutex_lock; pthread_t self; /* my thread ID */ schedule_t *schedule; /* event processing */ /* packet parsing storage */ u_char buffer[BGPMAXPACKETSIZE * 2]; u_char *read_ptr; /* current ptr of read in buffer */ u_char *start_ptr; /* current ptr of start of packet */ u_char *packet; /* pointer to the packet */ accept_socket_t *accept_socket; #if 0 u_char buffer_in[BGPMAXPACKETSIZE]; u_char *read_ptr_in; /* current ptr of read in buffer */ int sockfd_in; /* sockect connected to peer (incoming) */ #endif LINKED_LIST *send_queue; pthread_mutex_t send_mutex_lock; /* timers */ mtimer_t *timer_Start; mtimer_t *timer_ConnectRetry; mtimer_t *timer_KeepAlive; mtimer_t *timer_HoldTime; /* time value of intervals in seconds */ int Start_Interval; int ConnectRetry_Interval; int KeepAlive_Interval; int HoldTime_Interval; /* tracing stuff */ trace_t *trace; time_t time; int maximum_prefix; bgp_filters_t filters[MAX_BGP_VIEWS]; /* filters per view */ int default_weight[MAX_BGP_VIEWS]; int state; int code; int subcode; LINKED_LIST *ll_announce; LINKED_LIST *ll_withdraw; bgp_attr_t *attr; int safi; LINKED_LIST *ll_update_out; pthread_mutex_t update_mutex_lock; /* statistics */ u_long num_packets_recv; u_long num_notifications_recv; u_long num_updates_recv; u_long num_packets_sent; u_long num_notifications_sent; u_long num_updates_sent; u_long num_connections_established; u_long num_connections_dropped; /* store incoming routes (rib_in) */ radix_tree_t *routes_in[AFI_MAX][SAFI_MAX]; time_t routes_in_check_time; #define AFISAFI2CAP(afi, safi) (1 << ((((afi) - 1) << 2) + ((safi) - 1))) u_long cap_opt_requesting; u_long cap_opt_received; u_long cap_opt_negotiated; } bgp_peer_t; #include typedef struct _bgp_t { int cport; /* port to send out open on */ int lport; /* port to listen for open on */ int default_local_pref; LINKED_LIST *ll_bgp_locals; /* linked list of bgp routers */ pthread_mutex_t locals_mutex_lock; /* a lock for ll_bgp_locals */ int accept_all_peers; trace_t *trace; LINKED_LIST *ll_listen_sockets; HASH_TABLE *attr_hash; /* hash of bgp attribute blocks */ struct _view_t *views[MAX_BGP_VIEWS]; bgp_bitset_t view_mask; /* which views are defined */ schedule_t *schedule; /* event processing */ void (*peer_down_call_fn) (); int (*update_call_fn) (); void (*state_change_fn) (); void (*peer_established_call_fn) (); int (*send_update_call_fn) (); /* Since view is created dynamically, there may be a dump request without a real view */ char *dump_route_form[MAX_BGP_VIEWS]; time_t dump_route_interval[MAX_BGP_VIEWS]; time_t dump_route_time[MAX_BGP_VIEWS]; int dump_route_type[MAX_BGP_VIEWS]; /* DUMP_ASCII or DUMP_BINARY */ int dump_new_format; /* bool */ int dump_direction; /* 1 -- receiving, 2 -- sending, 3 -- both */ char *dump_update_form; time_t dump_update_interval; time_t dump_update_time; u_long dump_update_types; int dump_update_family; pthread_mutex_t mutex_lock; time_t Default_Start_Interval; time_t Default_ConnectRetry_Interval; time_t Default_KeepAlive_Interval; time_t Default_HoldTime_Interval; mtimer_t *timer_house_keeping; u_int bgp_num_active_route_head; u_int bgp_num_active_route_node; HASH_TABLE *nexthop_hash_table; } bgp_t; extern bgp_t *BGP; enum BGP_ATTR { BGP_NULL = 0, BGP_MY_AS, BGP_MY_ID, BGP_CURRENT_BGP, BGP_TRACE_STRUCT, BGP_PEER_DOWN_FN, BGP_PEER_ESTABLISHED_FN, BGP_RECV_UPDATE_FN, BGP_STATE_CHANGE_FN, BGP_SEND_UPDATE_FN, /* call this routine when sending updates */ BGP_ACCEPT_ALL_PEERS, /* start peering sesssion with anyone */ BGP_LPORT, /* port to listen for connections on */ BGP_CPORT, /* port to attempt connections to */ BGP_USE_PORTSERVER, /* use portserver library for listening */ BGP_DUMP_ROUTE_FORM, /* a file name used in dumping a route table */ BGP_DUMP_UPDATE_FORM, /* a file name used in dumping updates */ BGP_DUMP_DIRECTION /* 1 -- receiving, 2 -- sending, 3 -- both */ }; enum BGP_PEER_ATTR { BGP_PEER_NULL = 0, BGP_PEER_AS, BGP_PEER_ROUTER_ID, BGP_PEER_DESCRIPTION, BGP_PEER_VIEW, BGP_PEER_WEIGHT, BGP_PEER_ALIAS_ADD, BGP_PEER_ALIAS_DEL, BGP_PEER_MAXPREF, BGP_PEER_SETOPT, BGP_PEER_RESETOPT, BGP_PEER_DLIST_IN, BGP_PEER_DLIST_OUT, BGP_PEER_FLIST_IN, BGP_PEER_FLIST_OUT, BGP_PEER_CLIST_IN, BGP_PEER_CLIST_OUT, BGP_PEER_RTMAP_IN, BGP_PEER_RTMAP_OUT, BGP_PEER_HOLDTIME, BGP_PEER_KEEPALIVE, BGP_PEER_CONNECTRETRY, BGP_PEER_START }; /* a convenience structure to store all prefixes with same BGP * attributes while we are building BGP update packets */ typedef struct _bgp_bucket_t { LINKED_LIST *ll_prefix; bgp_attr_t *attr; } bgp_bucket_t; typedef struct _bgp_packet_t { short len, offset; u_char *data; } bgp_packet_t; /* in bgp_pdu.c */ int bgp_read (bgp_peer_t * peer, int sockfd, u_char * ptr, int len); int bgp_get_pdu (bgp_peer_t * peer); int bgp_flush_queue (bgp_peer_t * peer); void bgp_packet_del (bgp_packet_t *bgp_packet); int bgp_process_update (bgp_peer_t * peer); int bgp_process_open (bgp_peer_t * peer); int bgp_process_notify (bgp_peer_t * peer); int bgp_send_open (bgp_peer_t * peer); int bgp_send_keepalive (bgp_peer_t * peer); int bgp_send_notification (bgp_peer_t * peer, int code, int subcode); int bgp_send_notification2 (int sockfd, prefix_t * prefix, int port, int code, int subcode); int bgp_send_notify_byte (bgp_peer_t * peer, int code, int subcode, int opt); int bgp_send_notify_word (bgp_peer_t * peer, int code, int subcode, int opt); int bgp_send_update (bgp_peer_t * peer, int len, u_char * data); void bgp_reset_cap_opt (bgp_peer_t *peer); /* in bgp_util.c */ int bgp_in_recv_open (bgp_peer_t *peer); int peer_set_gateway (bgp_peer_t *peer, int as, u_long id); char *bgp_notify_to_string (int code, int subcode); char *bgpmessage2string (int type); int bgp_start_transport_connection (bgp_peer_t * peer); void bgp_release_resources (bgp_peer_t * peer); bgp_peer_t *Find_BGP_Peer (bgp_local_t *local_bgp, prefix_t * prefix, int as, u_long id); bgp_peer_t *Find_BGP_Peer_ByID (bgp_local_t *local_bgp, char *name); bgp_peer_t *Add_BGP_Peer (bgp_local_t *local_bgp, char *name, prefix_t * prefix, int as, u_long id, trace_t * trace); void Destroy_BGP_Peer (bgp_peer_t * peer, int fast); void bgp_flush_socket (bgp_peer_t * peer); void bgp_broken_pipe (void); void bgp_die (void); int bgp_kill_peer (gateway_t * gateway); void bgp_stop_peer (bgp_peer_t * peer); void bgp_start_peer (bgp_peer_t * peer); void bgp_kill_all (bgp_local_t *local_bgp); void bgp_start_all (bgp_local_t *local_bgp); /* void default_bgp_peer_down_fd (bgp_peer_t * peer); */ void bgp_start_peer_thread (bgp_peer_t * peer); void bgp_start_main_thread (); bgp_peer_t *find_bgp_peer (gateway_t * gateway); void peer_set_as (bgp_peer_t *peer, int as); bgp_local_t *init_bgp_local (int as, u_long id); void remove_bgp_local (bgp_local_t *local_bgp); int show_bgp_local (uii_connection_t * uii); int show_bgp_views (uii_connection_t * uii); void bgp_peer_down (bgp_peer_t * peer); void bgp_peer_dead (bgp_peer_t * peer); void dump_text_bgp_view (uii_connection_t * uii, view_t *view); int set_BGP (int first, ...); void start_bgp (void); void stop_bgp (void); void start_bgp_peer (bgp_peer_t * peer); void bgp_start_listening (bgp_peer_t *peer); int trace_bgp (uii_connection_t * uii); int bgp_check_attr (bgp_peer_t * peer, bgp_attr_t * attr, int as); int check_bgp_networks (prefix_t *prefix, int viewno); listen_socket_t * init_BGP_listen (prefix_t *bind_addr, interface_t *bind_if); int show_f_bgp (uii_connection_t * uii, int family); int show_f_bgp_summary (uii_connection_t * uii, bgp_local_t *local_bgp, int family, int summary); int show_f_bgp_rt_view_regexp (uii_connection_t * uii, int family, int viewno, char *expr, char *filtered); int show_bgp_rt_view_prefix (uii_connection_t * uii, int viewno, prefix_t *prefix, char *options, char *filtered); int show_f_bgp_neighbors_routes (uii_connection_t * uii, int family, int viewno, char *peer_or_star, char *filtered); int show_f_bgp_neighbors_errors (uii_connection_t * uii, int family, char *peer_or_star); /* in bgp_sm.c */ void bgp_change_state (bgp_peer_t * peer, int state, int event); #ifdef notdef void bgp_sm_state_idle (bgp_peer_t * peer, int event); void bgp_sm_state_active (bgp_peer_t * peer, int event); void bgp_sm_state_connect (bgp_peer_t * peer, int event); void bgp_sm_state_opensent (bgp_peer_t * peer, int event); void bgp_sm_state_openconfirm (bgp_peer_t * peer, int event); void bgp_sm_state_established (bgp_peer_t * peer, int event); #endif void bgp_sm_process_event (bgp_peer_t * peer, int event); /* in bgp_timer.c */ void bgp_timer_ConnectRetry_fire (mtimer_t * timer, bgp_peer_t * peer); void bgp_timer_KeepAlive_fire (mtimer_t * timer, bgp_peer_t * peer); void bgp_timer_HoldTime_fire (mtimer_t * timer, bgp_peer_t * peer); void bgp_timer_StartTime_fire (mtimer_t * timer, bgp_peer_t * peer); /* in bgp_thread.c */ void bgp_schedule_timer (mtimer_t * timer, bgp_peer_t * peer); void bgp_schedule_socket (bgp_peer_t * peer); void bgp_get_config_neighbor (bgp_peer_t * peer); void bgp_schedule_get_config_neighbor (bgp_peer_t * peer); /* public functions */ void init_BGP (trace_t * ltrace); /* bgp_dump.c */ void bgp_write_mrt_msg (bgp_peer_t * peer, enum MRT_MSG_BGP_TYPES bgptype, u_char * buf, int length); void bgp_write_status_change (bgp_peer_t * peer, u_short state); int bgp_table_dump_write (int fd, int type, int subtype, int viewno, int seq_num, u_char *pp, int len); u_char *bgp_table_dump_entry (u_char *cp, u_char *end, int type, int subtype, int viewno, prefix_t *prefix, int status, time_t originated, bgp_attr_t *attr); bgp_peer_t * create_fake_peer (void); int dump_view_bgp_routes (int viewno, char *filename, int dump_type); #define Find_BGP_Peer_ByPrefix(local_bgp, prefix) \ Find_BGP_Peer(local_bgp, prefix, 0, 0) #undef bgp_attr_t #endif /* _BGP_H */ .