3 * Used to advertise routes for upstream (l2tp port, rather than gratiutious
4 * arp) and downstream--allowing routers to load-balance both.
6 * Implementation limitations:
7 * - We never listen for incoming connections (session always initiated by us).
8 * - Any routes advertised by the peer are accepted, but ignored.
9 * - No password support; neither RFC1771 (which no-one seems to do anyway)
10 * nor RFC2385 (which requires a kernel patch on 2.4 kernels).
13 char const *cvs_id_bgp
= "$Id: bgp.c,v 1.3 2004/08/13 00:02:50 fred_nerk Exp $";
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
30 static void bgp_clear(struct bgp_peer
*peer
);
31 static void bgp_set_retry(struct bgp_peer
*peer
);
32 static void bgp_cidr(in_addr_t ip
, in_addr_t mask
, struct bgp_ip_prefix
*pfx
);
33 static struct bgp_route_list
*bgp_insert_route(struct bgp_route_list
*head
,
34 struct bgp_route_list
*new);
36 static void bgp_free_routes(struct bgp_route_list
*routes
);
37 static char const *bgp_state_str(enum bgp_state state
);
38 static char const *bgp_msg_type_str(u8 type
);
39 static int bgp_connect(struct bgp_peer
*peer
);
40 static int bgp_handle_connect(struct bgp_peer
*peer
);
41 static int bgp_write(struct bgp_peer
*peer
);
42 static int bgp_read(struct bgp_peer
*peer
);
43 static int bgp_handle_input(struct bgp_peer
*peer
);
44 static int bgp_send_open(struct bgp_peer
*peer
);
45 static int bgp_send_keepalive(struct bgp_peer
*peer
);
46 static int bgp_send_update(struct bgp_peer
*peer
);
47 static int bgp_send_notification(struct bgp_peer
*peer
, u8 code
, u8 subcode
);
51 /* prepare peer structure, globals */
55 struct bgp_peer
*peer
;
57 for (i
= 0; i
< BGP_NUM_PEERS
; i
++)
60 memset(peer
, 0, sizeof(*peer
));
62 peer
->addr
= INADDR_NONE
;
64 peer
->state
= peer
->next_state
= Disabled
;
66 if (!((peer
->outbuf
= malloc(sizeof(*peer
->outbuf
))) && (peer
->inbuf
= malloc(sizeof(*peer
->inbuf
)))))
68 log(0, 0, 0, 0, "Can't allocate buffers for bgp peer (%s)\n",
82 bgp_configured
= 0; /* set by bgp_start */
87 /* start connection with a peer */
88 int bgp_start(struct bgp_peer
*peer
, char *name
, int as
, int enable
)
93 struct bgp_path_attr a
;
97 u32 metric
= htonl(BGP_METRIC
);
98 u32 no_export
= htonl(BGP_COMMUNITY_NO_EXPORT
);
103 if (peer
->state
!= Disabled
)
106 snprintf(peer
->name
, sizeof(peer
->name
), "%s", name
);
108 if (!(h
= gethostbyname(name
)) || h
->h_addrtype
!= AF_INET
)
110 log(0, 0, 0, 0, "Can't get address for BGP peer %s (%s)\n", name
, h
? "no address" : hstrerror(h_errno
));
115 memcpy(&peer
->addr
, h
->h_addr
, sizeof(peer
->addr
));
116 peer
->as
= as
> 0 ? as
: our_as
;
117 ibgp
= peer
->as
== our_as
;
119 /* clear buffers, go to Idle state */
120 peer
->next_state
= Idle
;
123 /* set initial routing state */
124 peer
->routing
= enable
;
126 /* all our routes use the same attributes, so prepare it in advance */
127 if (peer
->path_attrs
)
128 free(peer
->path_attrs
);
130 peer
->path_attr_len
= 0;
133 a
.flags
= BGP_PATH_ATTR_FLAG_TRANS
;
134 a
.code
= BGP_PATH_ATTR_CODE_ORIGIN
;
136 a
.data
.s
.value
[0] = BGP_PATH_ATTR_CODE_ORIGIN_IGP
;
138 #define ADD_ATTRIBUTE() do { \
139 i = BGP_PATH_ATTR_SIZE(a); \
142 peer->path_attr_len += i; } while (0)
147 a
.flags
= BGP_PATH_ATTR_FLAG_TRANS
;
148 a
.code
= BGP_PATH_ATTR_CODE_AS_PATH
;
162 BGP_PATH_ATTR_CODE_AS_PATH_AS_SEQUENCE
,
167 a
.data
.s
.len
= sizeof(as_path
);
168 memcpy(&a
.data
.s
.value
, &as_path
, sizeof(as_path
));
174 a
.flags
= BGP_PATH_ATTR_FLAG_TRANS
;
175 a
.code
= BGP_PATH_ATTR_CODE_NEXT_HOP
;
176 ip
= my_address
; /* we're it */
177 a
.data
.s
.len
= sizeof(ip
);
178 memcpy(a
.data
.s
.value
, &ip
, sizeof(ip
));
182 /* MULTI_EXIT_DISC */
183 a
.flags
= BGP_PATH_ATTR_FLAG_OPTIONAL
;
184 a
.code
= BGP_PATH_ATTR_CODE_MULTI_EXIT_DISC
;
185 a
.data
.s
.len
= sizeof(metric
);
186 memcpy(a
.data
.s
.value
, &metric
, sizeof(metric
));
192 u32 local_pref
= htonl(BGP_LOCAL_PREF
);
195 a
.flags
= BGP_PATH_ATTR_FLAG_TRANS
;
196 a
.code
= BGP_PATH_ATTR_CODE_LOCAL_PREF
;
197 a
.data
.s
.len
= sizeof(local_pref
);
198 memcpy(a
.data
.s
.value
, &local_pref
, sizeof(local_pref
));
204 a
.flags
= BGP_PATH_ATTR_FLAG_OPTIONAL
| BGP_PATH_ATTR_FLAG_TRANS
;
205 a
.code
= BGP_PATH_ATTR_CODE_COMMUNITIES
;
206 a
.data
.s
.len
= sizeof(no_export
);
207 memcpy(a
.data
.s
.value
, &no_export
, sizeof(no_export
));
211 if (!(peer
->path_attrs
= malloc(peer
->path_attr_len
)))
213 log(0, 0, 0, 0, "Can't allocate path_attrs for %s (%s)\n",
214 name
, strerror(errno
));
219 memcpy(peer
->path_attrs
, path_attrs
, peer
->path_attr_len
);
221 log(4, 0, 0, 0, "Initiating BGP connection to %s (routing %s)\n",
222 name
, enable
? "enabled" : "suspended");
224 /* we have at least one peer configured */
228 return bgp_connect(peer
);
231 /* clear counters, timers, routes and buffers; close socket; move to
232 next_state, which may be Disabled or Idle */
233 static void bgp_clear(struct bgp_peer
*peer
)
235 if (peer
->sock
!= -1)
241 peer
->keepalive_time
= 0;
243 peer
->expire_time
= 0;
245 bgp_free_routes(peer
->routes
);
248 peer
->outbuf
->packet
.header
.len
= 0;
249 peer
->outbuf
->done
= 0;
250 peer
->inbuf
->packet
.header
.len
= 0;
251 peer
->inbuf
->done
= 0;
255 if (peer
->state
!= peer
->next_state
)
257 peer
->state
= peer
->next_state
;
258 peer
->state_time
= time_now
;
260 log(4, 0, 0, 0, "BGP peer %s: state %s\n", peer
->name
,
261 bgp_state_str(peer
->next_state
));
265 /* initiate a clean shutdown */
266 void bgp_stop(struct bgp_peer
*peer
)
268 log(4, 0, 0, 0, "Terminating BGP connection to %s\n", peer
->name
);
269 bgp_send_notification(peer
, BGP_ERR_CEASE
, 0);
272 /* drop connection (if any) and set state to Disabled */
273 void bgp_halt(struct bgp_peer
*peer
)
275 log(4, 0, 0, 0, "Aborting BGP connection to %s\n", peer
->name
);
276 peer
->next_state
= Disabled
;
280 /* drop connection (if any) and set to Idle for connection retry */
281 int bgp_restart(struct bgp_peer
*peer
)
283 peer
->next_state
= Idle
;
287 peer
->retry_time
= time_now
;
288 peer
->retry_count
= 0;
291 return bgp_connect(peer
);
294 static void bgp_set_retry(struct bgp_peer
*peer
)
296 if (peer
->retry_count
++ < BGP_MAX_RETRY
)
298 peer
->retry_time
= time_now
+ (BGP_RETRY_BACKOFF
* peer
->retry_count
);
299 peer
->next_state
= Idle
;
303 bgp_halt(peer
); /* give up */
306 /* convert ip/mask to CIDR notation */
307 static void bgp_cidr(in_addr_t ip
, in_addr_t mask
, struct bgp_ip_prefix
*pfx
)
312 /* convert to prefix notation */
316 if (!mask
) /* bogus */
319 for (i
= 0; i
< 32 && ((b
= ntohl(1 << i
)), !(mask
& b
)); i
++)
326 /* insert route into list; sorted */
327 static struct bgp_route_list
*bgp_insert_route(struct bgp_route_list
*head
,
328 struct bgp_route_list
*new)
330 struct bgp_route_list
*p
= head
;
331 struct bgp_route_list
*e
= 0;
333 while (p
&& memcmp(&p
->dest
, &new->dest
, sizeof(p
->dest
)) < 0)
353 /* add route to list for peers */
355 * Note: this doesn't do route aggregation, nor drop routes if a less
356 * specific match already exists (partly because I'm lazy, but also so
357 * that if that route is later deleted we don't have to be concerned
358 * about adding back the more specific one).
360 int bgp_add_route(in_addr_t ip
, in_addr_t mask
)
362 struct bgp_route_list
*r
= bgp_routes
;
363 struct bgp_route_list add
;
366 bgp_cidr(ip
, mask
, &add
.dest
);
369 /* check for duplicate */
372 i
= memcmp(&r
->dest
, &add
.dest
, sizeof(r
->dest
));
374 return 1; /* already covered */
382 /* insert into route list; sorted */
383 if (!(r
= malloc(sizeof(*r
))))
385 log(0, 0, 0, 0, "Can't allocate route for %s/%d (%s)\n",
386 inet_toa(add
.dest
.prefix
), add
.dest
.len
, strerror(errno
));
391 memcpy(r
, &add
, sizeof(*r
));
392 bgp_routes
= bgp_insert_route(bgp_routes
, r
);
394 /* flag established peers for update */
395 for (i
= 0; i
< BGP_NUM_PEERS
; i
++)
396 if (bgp_peers
[i
].state
== Established
)
397 bgp_peers
[i
].update_routes
= 1;
399 log(4, 0, 0, 0, "Registered BGP route %s/%d\n", inet_toa(add
.dest
.prefix
),
405 /* remove route from list for peers */
406 int bgp_del_route(in_addr_t ip
, in_addr_t mask
)
408 struct bgp_route_list
*r
= bgp_routes
;
409 struct bgp_route_list
*e
= 0;
410 struct bgp_route_list del
;
413 bgp_cidr(ip
, mask
, &del
.dest
);
416 /* find entry in routes list and remove */
419 i
= memcmp(&r
->dest
, &del
.dest
, sizeof(r
->dest
));
425 bgp_routes
= r
->next
;
443 /* flag established peers for update */
444 for (i
= 0; i
< BGP_NUM_PEERS
; i
++)
445 if (bgp_peers
[i
].state
== Established
)
446 bgp_peers
[i
].update_routes
= 1;
448 log(4, 0, 0, 0, "Removed BGP route %s/%d\n", inet_toa(del
.dest
.prefix
),
454 /* enable or disable routing */
455 void bgp_enable_routing(int enable
)
459 for (i
= 0; i
< BGP_NUM_PEERS
; i
++)
461 bgp_peers
[i
].routing
= enable
;
463 /* flag established peers for update */
464 if (bgp_peers
[i
].state
== Established
)
465 bgp_peers
[i
].update_routes
= 1;
468 log(4, 0, 0, 0, "%s BGP routing\n", enable
? "Enabled" : "Suspended");
471 /* return a bitmask indicating if the socket should be added to the
472 read set (1) and or write set (2) for select */
473 int bgp_select_state(struct bgp_peer
*peer
)
480 if (peer
->state
== Disabled
|| peer
->state
== Idle
)
483 if (peer
->inbuf
->done
< BGP_MAX_PACKET_SIZE
)
486 if (peer
->state
== Connect
|| /* connection in progress */
487 peer
->update_routes
|| /* routing updates */
488 peer
->outbuf
->packet
.header
.len
) /* pending output */
494 /* process bgp peer */
495 int bgp_process(struct bgp_peer
*peer
, int readable
, int writable
)
500 if (*peer
->name
&& peer
->cli_flag
== BGP_CLI_RESTART
)
501 return bgp_restart(peer
);
503 if (peer
->state
== Disabled
)
508 switch (peer
->cli_flag
)
510 case BGP_CLI_SUSPEND
:
514 if (peer
->state
== Established
)
515 peer
->update_routes
= 1;
524 if (peer
->state
== Established
)
525 peer
->update_routes
= 1;
534 /* handle empty/fill of buffers */
538 if (peer
->state
== Connect
)
539 r
= bgp_handle_connect(peer
);
540 else if (peer
->outbuf
->packet
.header
.len
)
553 /* process input buffer contents */
554 while (peer
->inbuf
->done
>= sizeof(peer
->inbuf
->packet
.header
)
555 && !peer
->outbuf
->packet
.header
.len
) /* may need to queue a response */
557 if (bgp_handle_input(peer
) < 0)
561 /* process pending updates */
562 if (peer
->update_routes
563 && !peer
->outbuf
->packet
.header
.len
) /* ditto */
565 if (!bgp_send_update(peer
))
570 if (peer
->state
== Established
)
572 if (time_now
> peer
->expire_time
)
574 log(1, 0, 0, 0, "No message from BGP peer %s in %ds\n",
575 peer
->name
, peer
->hold
);
577 bgp_send_notification(peer
, BGP_ERR_HOLD_TIMER_EXP
, 0);
581 if (time_now
> peer
->keepalive_time
&& !peer
->outbuf
->packet
.header
.len
)
582 bgp_send_keepalive(peer
);
584 else if (peer
->state
== Idle
)
586 if (time_now
> peer
->retry_time
)
587 return bgp_connect(peer
);
589 else if (time_now
> peer
->state_time
+ BGP_KEEPALIVE_TIME
)
591 log(1, 0, 0, 0, "%s timer expired for BGP peer %s\n",
592 bgp_state_str(peer
->state
), peer
->name
);
594 return bgp_restart(peer
);
600 static void bgp_free_routes(struct bgp_route_list
*routes
)
602 struct bgp_route_list
*tmp
;
604 while ((tmp
= routes
))
611 static char const *bgp_state_str(enum bgp_state state
)
615 case Disabled
: return "Disabled";
616 case Idle
: return "Idle";
617 case Connect
: return "Connect";
618 case Active
: return "Active";
619 case OpenSent
: return "OpenSent";
620 case OpenConfirm
: return "OpenConfirm";
621 case Established
: return "Established";
627 static char const *bgp_msg_type_str(u8 type
)
631 case BGP_MSG_OPEN
: return "OPEN";
632 case BGP_MSG_UPDATE
: return "UPDATE";
633 case BGP_MSG_NOTIFICATION
: return "NOTIFICATION";
634 case BGP_MSG_KEEPALIVE
: return "KEEPALIVE";
640 /* attempt to connect to peer */
641 static int bgp_connect(struct bgp_peer
*peer
)
643 static int bgp_port
= 0;
644 struct sockaddr_in addr
;
648 struct servent
*serv
;
649 if (!(serv
= getservbyname("bgp", "tcp")))
651 log(0, 0, 0, 0, "Can't get bgp service (%s)\n", strerror(errno
));
655 bgp_port
= serv
->s_port
;
658 if ((peer
->sock
= socket(PF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) < 0)
660 log(0, 0, 0, 0, "Can't create a socket for BGP peer %s (%s)\n",
661 peer
->name
, strerror(errno
));
663 peer
->state
= peer
->next_state
= Disabled
;
667 /* set to non-blocking */
668 fcntl(peer
->sock
, F_SETFL
, fcntl(peer
->sock
, F_GETFL
, 0) | O_NONBLOCK
);
671 memset(&addr
, 0, sizeof(addr
));
672 addr
.sin_family
= AF_INET
;
673 addr
.sin_port
= bgp_port
;
674 addr
.sin_addr
.s_addr
= peer
->addr
;
676 while (connect(peer
->sock
, (struct sockaddr
*) &addr
, sizeof(addr
)) == -1)
678 if (errno
== EINTR
) /* SIGALARM handler */
681 if (errno
!= EINPROGRESS
)
683 log(1, 0, 0, 0, "Can't connect to BGP peer %s (%s)\n",
684 inet_ntoa(addr
.sin_addr
), strerror(errno
));
690 peer
->state
= Connect
;
691 peer
->state_time
= time_now
;
693 log(4, 0, 0, 0, "BGP peer %s: state Connect\n", peer
->name
);
697 peer
->state
= Active
;
698 peer
->state_time
= time_now
;
699 peer
->retry_time
= peer
->retry_count
= 0;
701 log(4, 0, 0, 0, "BGP peer %s: state Active\n", inet_ntoa(addr
.sin_addr
));
703 return bgp_send_open(peer
);
706 /* complete partial connection (state = Connect) */
707 static int bgp_handle_connect(struct bgp_peer
*peer
)
710 int len
= sizeof(int);
711 getsockopt(peer
->sock
, SOL_SOCKET
, SO_ERROR
, &err
, &len
);
714 log(1, 0, 0, 0, "Can't connect to BGP peer %s (%s)\n", peer
->name
,
721 peer
->state
= Active
;
722 peer
->state_time
= time_now
;
724 log(4, 0, 0, 0, "BGP peer %s: state Active\n", peer
->name
);
726 return bgp_send_open(peer
);
729 /* initiate a write */
730 static int bgp_write(struct bgp_peer
*peer
)
732 int len
= htons(peer
->outbuf
->packet
.header
.len
);
735 while ((r
= write(peer
->sock
, &peer
->outbuf
->packet
+ peer
->outbuf
->done
,
736 len
- peer
->outbuf
->done
)) == -1)
745 log(1, 0, 0, 0, "Connection to BGP peer %s closed\n", peer
->name
);
747 log(1, 0, 0, 0, "Can't write to BGP peer %s (%s)\n", peer
->name
,
756 peer
->outbuf
->done
+= r
;
760 log(4, 0, 0, 0, "Sent %s to BGP peer %s\n",
761 bgp_msg_type_str(peer
->outbuf
->packet
.header
.type
), peer
->name
);
763 peer
->outbuf
->packet
.header
.len
= 0;
764 peer
->outbuf
->done
= 0;
766 if (peer
->state
== Established
)
767 peer
->keepalive_time
= time_now
+ BGP_KEEPALIVE_TIME
;
769 if (peer
->state
!= peer
->next_state
)
771 if (peer
->next_state
== Disabled
|| peer
->next_state
== Idle
)
777 peer
->state
= peer
->next_state
;
778 peer
->state_time
= time_now
;
780 log(4, 0, 0, 0, "BGP peer %s: state %s\n", peer
->name
,
781 bgp_state_str(peer
->state
));
787 /* initiate a read */
788 static int bgp_read(struct bgp_peer
*peer
)
792 while ((r
= read(peer
->sock
, &peer
->inbuf
->packet
+ peer
->inbuf
->done
,
793 BGP_MAX_PACKET_SIZE
- peer
->inbuf
->done
)) < 1)
797 log(1, 0, 0, 0, "Connection to BGP peer %s closed\n", peer
->name
);
807 log(1, 0, 0, 0, "Can't read from BGP peer %s (%s)\n", peer
->name
,
815 peer
->inbuf
->done
+= r
;
819 /* process buffered packets */
820 static int bgp_handle_input(struct bgp_peer
*peer
)
822 struct bgp_packet
*p
= &peer
->inbuf
->packet
;
823 int len
= ntohs(p
->header
.len
);
825 if (len
> BGP_MAX_PACKET_SIZE
)
827 log(1, 0, 0, 0, "Bad header length from BGP %s\n", peer
->name
);
828 bgp_send_notification(peer
, BGP_ERR_HEADER
, BGP_ERR_HDR_BAD_LEN
);
832 if (peer
->inbuf
->done
< len
)
835 log(4, 0, 0, 0, "Received %s from BGP peer %s\n",
836 bgp_msg_type_str(p
->header
.type
), peer
->name
);
838 switch (p
->header
.type
)
842 struct bgp_data_open data
;
845 for (i
= 0; i
< sizeof(p
->header
.marker
); i
++)
847 if ((unsigned char) p
->header
.marker
[i
] != 0xff)
849 log(1, 0, 0, 0, "Invalid marker from BGP peer %s\n",
852 bgp_send_notification(peer
, BGP_ERR_HEADER
,
853 BGP_ERR_HDR_NOT_SYNC
);
859 if (peer
->state
!= OpenSent
)
861 log(1, 0, 0, 0, "OPEN from BGP peer %s in %s state\n",
862 peer
->name
, bgp_state_str(peer
->state
));
864 bgp_send_notification(peer
, BGP_ERR_FSM
, 0);
868 memcpy(&data
, p
->data
, len
- sizeof(p
->header
));
870 if (data
.version
!= BGP_VERSION
)
872 log(1, 0, 0, 0, "Bad version (%d) sent by BGP peer %s\n",
873 (int) data
.version
, peer
->name
);
875 bgp_send_notification(peer
, BGP_ERR_OPEN
, BGP_ERR_OPN_VERSION
);
879 if (ntohs(data
.as
) != peer
->as
)
881 log(1, 0, 0, 0, "Bad AS sent by BGP peer %s (got %d, "
882 "expected %d)\n", peer
->name
, (int) htons(data
.as
),
885 bgp_send_notification(peer
, BGP_ERR_OPEN
, BGP_ERR_OPN_BAD_AS
);
889 if ((peer
->hold
= ntohs(data
.hold_time
)) < 10)
891 log(1, 0, 0, 0, "Bad hold time (%d) from BGP peer %s\n",
892 peer
->hold
, peer
->name
);
894 bgp_send_notification(peer
, BGP_ERR_OPEN
, BGP_ERR_OPN_HOLD_TIME
);
898 /* next transition requires an exchange of keepalives */
899 bgp_send_keepalive(peer
);
901 /* FIXME: may need to check for optional params */
906 case BGP_MSG_KEEPALIVE
:
907 if (peer
->state
== OpenConfirm
)
909 peer
->state
= peer
->next_state
= Established
;
910 peer
->state_time
= time_now
;
911 peer
->keepalive_time
= time_now
+ BGP_KEEPALIVE_TIME
;
912 peer
->update_routes
= 1;
913 peer
->retry_count
= 0;
914 peer
->retry_time
= 0;
916 log(4, 0, 0, 0, "BGP peer %s: state Established\n", peer
->name
);
921 case BGP_MSG_NOTIFICATION
:
922 if (len
> sizeof(p
->header
))
924 struct bgp_data_notification
*notification
=
925 (struct bgp_data_notification
*) p
->data
;
927 if (notification
->error_code
== BGP_ERR_CEASE
)
929 log(4, 0, 0, 0, "BGP peer %s sent CEASE\n", peer
->name
);
934 /* FIXME: should handle more notifications */
935 log(4, 0, 0, 0, "BGP peer %s sent unhandled NOTIFICATION %d\n",
936 peer
->name
, (int) notification
->error_code
);
943 peer
->expire_time
= time_now
+ peer
->hold
;
945 /* see if there's another message in the same packet/buffer */
946 if (peer
->inbuf
->done
> len
)
948 peer
->inbuf
->done
-= len
;
949 memmove(p
, (char *) p
+ len
, peer
->inbuf
->done
);
953 peer
->inbuf
->packet
.header
.len
= 0;
954 peer
->inbuf
->done
= 0;
957 return peer
->inbuf
->done
;
960 /* send/buffer OPEN message */
961 static int bgp_send_open(struct bgp_peer
*peer
)
963 struct bgp_data_open data
;
964 u16 len
= sizeof(peer
->outbuf
->packet
.header
);
966 memset(peer
->outbuf
->packet
.header
.marker
, 0xff,
967 sizeof(peer
->outbuf
->packet
.header
.marker
));
969 peer
->outbuf
->packet
.header
.type
= BGP_MSG_OPEN
;
971 data
.version
= BGP_VERSION
;
972 data
.as
= htons(our_as
);
973 data
.hold_time
= htons(BGP_HOLD_TIME
);
974 data
.identifier
= my_address
;
977 memcpy(peer
->outbuf
->packet
.data
, &data
, BGP_DATA_OPEN_SIZE
);
978 len
+= BGP_DATA_OPEN_SIZE
;
980 peer
->outbuf
->packet
.header
.len
= htons(len
);
981 peer
->outbuf
->done
= 0;
982 peer
->next_state
= OpenSent
;
984 return bgp_write(peer
);
987 /* send/buffer KEEPALIVE message */
988 static int bgp_send_keepalive(struct bgp_peer
*peer
)
990 memset(peer
->outbuf
->packet
.header
.marker
, 0xff,
991 sizeof(peer
->outbuf
->packet
.header
.marker
));
993 peer
->outbuf
->packet
.header
.type
= BGP_MSG_KEEPALIVE
;
994 peer
->outbuf
->packet
.header
.len
=
995 htons(sizeof(peer
->outbuf
->packet
.header
));
997 peer
->outbuf
->done
= 0;
998 peer
->next_state
= (peer
->state
== OpenSent
) ? OpenConfirm
: peer
->state
;
1000 return bgp_write(peer
);
1003 /* send/buffer UPDATE message */
1004 static int bgp_send_update(struct bgp_peer
*peer
)
1008 u16 len
= sizeof(peer
->outbuf
->packet
.header
);
1009 struct bgp_route_list
*have
= peer
->routes
;
1010 struct bgp_route_list
*want
= peer
->routing
? bgp_routes
: 0;
1011 struct bgp_route_list
*e
= 0;
1012 struct bgp_route_list
*add
= 0;
1015 char *data
= (char *) &peer
->outbuf
->packet
.data
;
1017 /* need leave room for attr_len, bgp_path_attrs and one prefix */
1018 char *max
= (char *) &peer
->outbuf
->packet
.data
1019 + sizeof(peer
->outbuf
->packet
.data
)
1020 - sizeof(attr_len
) - peer
->path_attr_len
- sizeof(struct bgp_ip_prefix
);
1022 /* skip over unf_len */
1023 data
+= sizeof(unf_len
);
1024 len
+= sizeof(unf_len
);
1026 memset(peer
->outbuf
->packet
.header
.marker
, 0xff,
1027 sizeof(peer
->outbuf
->packet
.header
.marker
));
1029 peer
->outbuf
->packet
.header
.type
= BGP_MSG_UPDATE
;
1031 peer
->update_routes
= 0; /* tentatively clear */
1033 /* find differences */
1034 while ((have
|| want
) && data
< (max
- sizeof(struct bgp_ip_prefix
)))
1038 ? memcmp(&have
->dest
, &want
->dest
, sizeof(have
->dest
))
1043 if (s
< 0) /* found one to delete */
1045 struct bgp_route_list
*tmp
= have
;
1048 s
= BGP_IP_PREFIX_SIZE(tmp
->dest
);
1049 memcpy(data
, &tmp
->dest
, s
);
1054 log(5, 0, 0, 0, "Withdrawing route %s/%d from BGP peer %s\n",
1055 inet_toa(tmp
->dest
.prefix
), tmp
->dest
.len
, peer
->name
);
1062 peer
->routes
= have
;
1068 e
= have
; /* stash the last found to relink above */
1072 else if (s
> 0) /* addition reqd. */
1076 peer
->update_routes
= 1; /* only one add per packet */
1090 peer
->update_routes
= 1; /* more to do */
1092 /* anything changed? */
1093 if (!(unf_len
|| add
))
1096 /* go back and insert unf_len */
1097 unf_len
= htons(unf_len
);
1098 memcpy(&peer
->outbuf
->packet
.data
, &unf_len
, sizeof(unf_len
));
1102 if (!(e
= malloc(sizeof(*e
))))
1104 log(0, 0, 0, 0, "Can't allocate route for %s/%d (%s)\n",
1105 inet_toa(add
->dest
.prefix
), add
->dest
.len
, strerror(errno
));
1110 memcpy(e
, add
, sizeof(*e
));
1112 peer
->routes
= bgp_insert_route(peer
->routes
, e
);
1114 attr_len
= htons(peer
->path_attr_len
);
1115 memcpy(data
, &attr_len
, sizeof(attr_len
));
1116 data
+= sizeof(attr_len
);
1117 len
+= sizeof(attr_len
);
1119 memcpy(data
, peer
->path_attrs
, peer
->path_attr_len
);
1120 data
+= peer
->path_attr_len
;
1121 len
+= peer
->path_attr_len
;
1123 s
= BGP_IP_PREFIX_SIZE(add
->dest
);
1124 memcpy(data
, &add
->dest
, s
);
1128 log(5, 0, 0, 0, "Advertising route %s/%d to BGP peer %s\n",
1129 inet_toa(add
->dest
.prefix
), add
->dest
.len
, peer
->name
);
1134 memcpy(data
, &attr_len
, sizeof(attr_len
));
1135 data
+= sizeof(attr_len
);
1136 len
+= sizeof(attr_len
);
1139 peer
->outbuf
->packet
.header
.len
= htons(len
);
1140 peer
->outbuf
->done
= 0;
1142 return bgp_write(peer
);
1145 /* send/buffer NOTIFICATION message */
1146 static int bgp_send_notification(struct bgp_peer
*peer
, u8 code
, u8 subcode
)
1148 struct bgp_data_notification data
;
1151 data
.error_code
= code
;
1152 len
+= sizeof(data
.error_code
);
1154 data
.error_subcode
= subcode
;
1155 len
+= sizeof(data
.error_code
);
1157 memset(peer
->outbuf
->packet
.header
.marker
, 0xff,
1158 sizeof(peer
->outbuf
->packet
.header
.marker
));
1160 peer
->outbuf
->packet
.header
.type
= BGP_MSG_NOTIFICATION
;
1161 peer
->outbuf
->packet
.header
.len
=
1162 htons(sizeof(peer
->outbuf
->packet
.header
) + len
);
1164 memcpy(peer
->outbuf
->packet
.data
, &data
, len
);
1166 peer
->outbuf
->done
= 0;
1167 peer
->next_state
= code
== BGP_ERR_CEASE
? Disabled
: Idle
;
1169 /* we're dying; ignore any pending input */
1170 peer
->inbuf
->packet
.header
.len
= 0;
1171 peer
->inbuf
->done
= 0;
1173 return bgp_write(peer
);
1180 int cmd_show_bgp(struct cli_def
*cli
, char *command
, char **argv
, int argc
)
1186 if (!bgp_configured
)
1189 if (CLI_HELP_REQUESTED
)
1190 return cli_arg_help(cli
, 1,
1191 "A.B.C.D", "BGP peer address",
1192 "NAME", "BGP peer name",
1195 cli_print(cli
, "BGPv%d router identifier %s, local AS number %d, "
1196 "hold time %ds", BGP_VERSION
, inet_toa(my_address
), (int) our_as
,
1201 for (i
= 0; i
< BGP_NUM_PEERS
; i
++)
1203 if (!*bgp_peers
[i
].name
)
1206 addr
= inet_toa(bgp_peers
[i
].addr
);
1207 if (argc
&& strcmp(addr
, argv
[0]) &&
1208 strncmp(bgp_peers
[i
].name
, argv
[0], strlen(argv
[0])))
1214 cli_print(cli
, "Peer AS Address "
1215 "State Retries Retry in Route Pend");
1216 cli_print(cli
, "------------------ ----- --------------- "
1217 "----------- ------- -------- ----- ----");
1220 cli_print(cli
, "%-18.18s %5d %15s %-11s %7d %7ds %5s %4s",
1224 bgp_state_str(bgp_peers
[i
].state
),
1225 bgp_peers
[i
].retry_count
,
1226 bgp_peers
[i
].retry_time
? bgp_peers
[i
].retry_time
- time_now
: 0,
1227 bgp_peers
[i
].routing
? "yes" : "no",
1228 bgp_peers
[i
].update_routes
? "yes" : "no");
1234 int cmd_suspend_bgp(struct cli_def
*cli
, char *command
, char **argv
, int argc
)
1239 if (!bgp_configured
)
1242 if (CLI_HELP_REQUESTED
)
1243 return cli_arg_help(cli
, 1,
1244 "A.B.C.D", "BGP peer address",
1245 "NAME", "BGP peer name",
1248 for (i
= 0; i
< BGP_NUM_PEERS
; i
++)
1250 if (bgp_peers
[i
].state
!= Established
)
1253 if (!bgp_peers
[i
].routing
)
1256 addr
= inet_toa(bgp_peers
[i
].addr
);
1257 if (argc
&& strcmp(addr
, argv
[0]) && strcmp(bgp_peers
[i
].name
, argv
[0]))
1260 bgp_peers
[i
].cli_flag
= BGP_CLI_SUSPEND
;
1261 cli_print(cli
, "Suspending peer %s", bgp_peers
[i
].name
);
1267 int cmd_no_suspend_bgp(struct cli_def
*cli
, char *command
, char **argv
, int argc
)
1272 if (!bgp_configured
)
1275 if (CLI_HELP_REQUESTED
)
1276 return cli_arg_help(cli
, 1,
1277 "A.B.C.D", "BGP peer address",
1278 "NAME", "BGP peer name",
1281 for (i
= 0; i
< BGP_NUM_PEERS
; i
++)
1283 if (bgp_peers
[i
].state
!= Established
)
1286 if (bgp_peers
[i
].routing
)
1289 addr
= inet_toa(bgp_peers
[i
].addr
);
1290 if (argc
&& strcmp(addr
, argv
[0]) &&
1291 strncmp(bgp_peers
[i
].name
, argv
[0], strlen(argv
[0])))
1294 bgp_peers
[i
].cli_flag
= BGP_CLI_ENABLE
;
1295 cli_print(cli
, "Un-suspending peer %s", bgp_peers
[i
].name
);
1301 int cmd_restart_bgp(struct cli_def
*cli
, char *command
, char **argv
, int argc
)
1306 if (!bgp_configured
)
1309 if (CLI_HELP_REQUESTED
)
1310 return cli_arg_help(cli
, 1,
1311 "A.B.C.D", "BGP peer address",
1312 "NAME", "BGP peer name",
1315 for (i
= 0; i
< BGP_NUM_PEERS
; i
++)
1317 if (!*bgp_peers
[i
].name
)
1320 addr
= inet_toa(bgp_peers
[i
].addr
);
1321 if (argc
&& strcmp(addr
, argv
[0]) && strncmp(bgp_peers
[i
].name
, argv
[0], strlen(argv
[0])))
1324 bgp_peers
[i
].cli_flag
= BGP_CLI_RESTART
;
1325 cli_print(cli
, "Restarting peer %s", bgp_peers
[i
].name
);