merge
[l2tpns.git] / bgp.c
1 /*
2 * BGPv4
3 * Used to advertise routes for upstream (l2tp port, rather than gratiutious
4 * arp) and downstream--allowing routers to load-balance both.
5 *
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).
11 */
12
13 char const *cvs_id_bgp = "$Id: bgp.c,v 1.4 2004-09-02 04:18:07 fred_nerk Exp $";
14
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <string.h>
18 #include <time.h>
19 #include <errno.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
23 #include <netdb.h>
24 #include <fcntl.h>
25
26 #include "l2tpns.h"
27 #include "bgp.h"
28 #include "util.h"
29
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);
35
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);
48
49 static u16 our_as;
50
51 /* prepare peer structure, globals */
52 int bgp_setup(int as)
53 {
54 int i;
55 struct bgp_peer *peer;
56
57 for (i = 0; i < BGP_NUM_PEERS; i++)
58 {
59 peer = &bgp_peers[i];
60 memset(peer, 0, sizeof(*peer));
61
62 peer->addr = INADDR_NONE;
63 peer->sock = -1;
64 peer->state = peer->next_state = Disabled;
65
66 if (!((peer->outbuf = malloc(sizeof(*peer->outbuf)))
67 && (peer->inbuf = malloc(sizeof(*peer->inbuf)))))
68 {
69 log(0, 0, 0, 0, "Can't allocate buffers for bgp peer (%s)\n",
70 strerror(errno));
71
72 return 0;
73 }
74 }
75
76 if (as < 1)
77 as = 0;
78
79 if ((our_as = as))
80 return 0;
81
82 bgp_routes = 0;
83 bgp_configured = 0; /* set by bgp_start */
84
85 return 1;
86 }
87
88 /* start connection with a peer */
89 int bgp_start(struct bgp_peer *peer, char *name, int as, int enable)
90 {
91 struct hostent *h;
92 int ibgp;
93 int i;
94 struct bgp_path_attr a;
95 char path_attrs[64];
96 char *p = path_attrs;
97 in_addr_t ip;
98 u32 metric = htonl(BGP_METRIC);
99 u32 no_export = htonl(BGP_COMMUNITY_NO_EXPORT);
100
101 if (!our_as)
102 return 0;
103
104 if (peer->state != Disabled)
105 bgp_halt(peer);
106
107 snprintf(peer->name, sizeof(peer->name), "%s", name);
108
109 if (!(h = gethostbyname(name)) || h->h_addrtype != AF_INET)
110 {
111 log(0, 0, 0, 0, "Can't get address for BGP peer %s (%s)\n",
112 name, h ? "no address" : hstrerror(h_errno));
113
114 return 0;
115 }
116
117 memcpy(&peer->addr, h->h_addr, sizeof(peer->addr));
118 peer->as = as > 0 ? as : our_as;
119 ibgp = peer->as == our_as;
120
121 /* clear buffers, go to Idle state */
122 peer->next_state = Idle;
123 bgp_clear(peer);
124
125 /* set initial routing state */
126 peer->routing = enable;
127
128 /* all our routes use the same attributes, so prepare it in advance */
129 if (peer->path_attrs)
130 free(peer->path_attrs);
131
132 peer->path_attr_len = 0;
133
134 /* ORIGIN */
135 a.flags = BGP_PATH_ATTR_FLAG_TRANS;
136 a.code = BGP_PATH_ATTR_CODE_ORIGIN;
137 a.data.s.len = 1;
138 a.data.s.value[0] = BGP_PATH_ATTR_CODE_ORIGIN_IGP;
139
140 #define ADD_ATTRIBUTE() do { \
141 i = BGP_PATH_ATTR_SIZE(a); \
142 memcpy(p, &a, i); \
143 p += i; \
144 peer->path_attr_len += i; } while (0)
145
146 ADD_ATTRIBUTE();
147
148 /* AS_PATH */
149 a.flags = BGP_PATH_ATTR_FLAG_TRANS;
150 a.code = BGP_PATH_ATTR_CODE_AS_PATH;
151 if (ibgp)
152 {
153 /* empty path */
154 a.data.s.len = 0;
155 }
156 else
157 {
158 /* just our AS */
159 struct {
160 u8 type;
161 u8 len;
162 u16 value;
163 } as_path = {
164 BGP_PATH_ATTR_CODE_AS_PATH_AS_SEQUENCE,
165 1,
166 htons(our_as),
167 };
168
169 a.data.s.len = sizeof(as_path);
170 memcpy(&a.data.s.value, &as_path, sizeof(as_path));
171 }
172
173 ADD_ATTRIBUTE();
174
175 /* NEXT_HOP */
176 a.flags = BGP_PATH_ATTR_FLAG_TRANS;
177 a.code = BGP_PATH_ATTR_CODE_NEXT_HOP;
178 ip = my_address; /* we're it */
179 a.data.s.len = sizeof(ip);
180 memcpy(a.data.s.value, &ip, sizeof(ip));
181
182 ADD_ATTRIBUTE();
183
184 /* MULTI_EXIT_DISC */
185 a.flags = BGP_PATH_ATTR_FLAG_OPTIONAL;
186 a.code = BGP_PATH_ATTR_CODE_MULTI_EXIT_DISC;
187 a.data.s.len = sizeof(metric);
188 memcpy(a.data.s.value, &metric, sizeof(metric));
189
190 ADD_ATTRIBUTE();
191
192 if (ibgp)
193 {
194 u32 local_pref = htonl(BGP_LOCAL_PREF);
195
196 /* LOCAL_PREF */
197 a.flags = BGP_PATH_ATTR_FLAG_TRANS;
198 a.code = BGP_PATH_ATTR_CODE_LOCAL_PREF;
199 a.data.s.len = sizeof(local_pref);
200 memcpy(a.data.s.value, &local_pref, sizeof(local_pref));
201
202 ADD_ATTRIBUTE();
203 }
204
205 /* COMMUNITIES */
206 a.flags = BGP_PATH_ATTR_FLAG_OPTIONAL | BGP_PATH_ATTR_FLAG_TRANS;
207 a.code = BGP_PATH_ATTR_CODE_COMMUNITIES;
208 a.data.s.len = sizeof(no_export);
209 memcpy(a.data.s.value, &no_export, sizeof(no_export));
210
211 ADD_ATTRIBUTE();
212
213 if (!(peer->path_attrs = malloc(peer->path_attr_len)))
214 {
215 log(0, 0, 0, 0, "Can't allocate path_attrs for %s (%s)\n",
216 name, strerror(errno));
217
218 return 0;
219 }
220
221 memcpy(peer->path_attrs, path_attrs, peer->path_attr_len);
222
223 log(4, 0, 0, 0, "Initiating BGP connection to %s (routing %s)\n",
224 name, enable ? "enabled" : "suspended");
225
226 /* we have at least one peer configured */
227 bgp_configured = 1;
228
229 /* connect */
230 return bgp_connect(peer);
231 }
232
233 /* clear counters, timers, routes and buffers; close socket; move to
234 next_state, which may be Disabled or Idle */
235 static void bgp_clear(struct bgp_peer *peer)
236 {
237 if (peer->sock != -1)
238 {
239 close(peer->sock);
240 peer->sock = -1;
241 }
242
243 peer->keepalive_time = 0;
244 peer->hold = 0;
245 peer->expire_time = 0;
246
247 bgp_free_routes(peer->routes);
248 peer->routes = 0;
249
250 peer->outbuf->packet.header.len = 0;
251 peer->outbuf->done = 0;
252 peer->inbuf->packet.header.len = 0;
253 peer->inbuf->done = 0;
254
255 peer->cli_flag = 0;
256
257 if (peer->state != peer->next_state)
258 {
259 peer->state = peer->next_state;
260 peer->state_time = time_now;
261
262 log(4, 0, 0, 0, "BGP peer %s: state %s\n", peer->name,
263 bgp_state_str(peer->next_state));
264 }
265 }
266
267 /* initiate a clean shutdown */
268 void bgp_stop(struct bgp_peer *peer)
269 {
270 log(4, 0, 0, 0, "Terminating BGP connection to %s\n", peer->name);
271 bgp_send_notification(peer, BGP_ERR_CEASE, 0);
272 }
273
274 /* drop connection (if any) and set state to Disabled */
275 void bgp_halt(struct bgp_peer *peer)
276 {
277 log(4, 0, 0, 0, "Aborting BGP connection to %s\n", peer->name);
278 peer->next_state = Disabled;
279 bgp_clear(peer);
280 }
281
282 /* drop connection (if any) and set to Idle for connection retry */
283 int bgp_restart(struct bgp_peer *peer)
284 {
285 peer->next_state = Idle;
286 bgp_clear(peer);
287
288 /* restart now */
289 peer->retry_time = time_now;
290 peer->retry_count = 0;
291
292 /* connect */
293 return bgp_connect(peer);
294 }
295
296 static void bgp_set_retry(struct bgp_peer *peer)
297 {
298 if (peer->retry_count++ < BGP_MAX_RETRY)
299 {
300 peer->retry_time = time_now + (BGP_RETRY_BACKOFF * peer->retry_count);
301 peer->next_state = Idle;
302 bgp_clear(peer);
303 }
304 else
305 bgp_halt(peer); /* give up */
306 }
307
308 /* convert ip/mask to CIDR notation */
309 static void bgp_cidr(in_addr_t ip, in_addr_t mask, struct bgp_ip_prefix *pfx)
310 {
311 int i;
312 u32 b;
313
314 /* convert to prefix notation */
315 pfx->len = 32;
316 pfx->prefix = ip;
317
318 if (!mask) /* bogus */
319 mask = 0xffffffff;
320
321 for (i = 0; i < 32 && ((b = ntohl(1 << i)), !(mask & b)); i++)
322 {
323 pfx->len--;
324 pfx->prefix &= ~b;
325 }
326 }
327
328 /* insert route into list; sorted */
329 static struct bgp_route_list *bgp_insert_route(struct bgp_route_list *head,
330 struct bgp_route_list *new)
331 {
332 struct bgp_route_list *p = head;
333 struct bgp_route_list *e = 0;
334
335 while (p && memcmp(&p->dest, &new->dest, sizeof(p->dest)) < 0)
336 {
337 e = p;
338 p = p->next;
339 }
340
341 if (e)
342 {
343 new->next = e->next;
344 e->next = new;
345 }
346 else
347 {
348 new->next = head;
349 head = new;
350 }
351
352 return head;
353 }
354
355 /* add route to list for peers */
356 /*
357 * Note: this doesn't do route aggregation, nor drop routes if a less
358 * specific match already exists (partly because I'm lazy, but also so
359 * that if that route is later deleted we don't have to be concerned
360 * about adding back the more specific one).
361 */
362 int bgp_add_route(in_addr_t ip, in_addr_t mask)
363 {
364 struct bgp_route_list *r = bgp_routes;
365 struct bgp_route_list add;
366 int i;
367
368 bgp_cidr(ip, mask, &add.dest);
369 add.next = 0;
370
371 /* check for duplicate */
372 while (r)
373 {
374 i = memcmp(&r->dest, &add.dest, sizeof(r->dest));
375 if (!i)
376 return 1; /* already covered */
377
378 if (i > 0)
379 break;
380
381 r = r->next;
382 }
383
384 /* insert into route list; sorted */
385 if (!(r = malloc(sizeof(*r))))
386 {
387 log(0, 0, 0, 0, "Can't allocate route for %s/%d (%s)\n",
388 inet_toa(add.dest.prefix), add.dest.len, strerror(errno));
389
390 return 0;
391 }
392
393 memcpy(r, &add, sizeof(*r));
394 bgp_routes = bgp_insert_route(bgp_routes, r);
395
396 /* flag established peers for update */
397 for (i = 0; i < BGP_NUM_PEERS; i++)
398 if (bgp_peers[i].state == Established)
399 bgp_peers[i].update_routes = 1;
400
401 log(4, 0, 0, 0, "Registered BGP route %s/%d\n", inet_toa(add.dest.prefix),
402 add.dest.len);
403
404 return 1;
405 }
406
407 /* remove route from list for peers */
408 int bgp_del_route(in_addr_t ip, in_addr_t mask)
409 {
410 struct bgp_route_list *r = bgp_routes;
411 struct bgp_route_list *e = 0;
412 struct bgp_route_list del;
413 int i;
414
415 bgp_cidr(ip, mask, &del.dest);
416 del.next = 0;
417
418 /* find entry in routes list and remove */
419 while (r)
420 {
421 i = memcmp(&r->dest, &del.dest, sizeof(r->dest));
422 if (!i)
423 {
424 if (e)
425 e->next = r->next;
426 else
427 bgp_routes = r->next;
428
429 free(r);
430 break;
431 }
432
433 e = r;
434
435 if (i > 0)
436 r = 0; /* stop */
437 else
438 r = r->next;
439 }
440
441 /* not found */
442 if (!r)
443 return 1;
444
445 /* flag established peers for update */
446 for (i = 0; i < BGP_NUM_PEERS; i++)
447 if (bgp_peers[i].state == Established)
448 bgp_peers[i].update_routes = 1;
449
450 log(4, 0, 0, 0, "Removed BGP route %s/%d\n", inet_toa(del.dest.prefix),
451 del.dest.len);
452
453 return 1;
454 }
455
456 /* enable or disable routing */
457 void bgp_enable_routing(int enable)
458 {
459 int i;
460
461 for (i = 0; i < BGP_NUM_PEERS; i++)
462 {
463 bgp_peers[i].routing = enable;
464
465 /* flag established peers for update */
466 if (bgp_peers[i].state == Established)
467 bgp_peers[i].update_routes = 1;
468 }
469
470 log(4, 0, 0, 0, "%s BGP routing\n", enable ? "Enabled" : "Suspended");
471 }
472
473 /* return a bitmask indicating if the socket should be added to the
474 read set (1) and or write set (2) for select */
475 int bgp_select_state(struct bgp_peer *peer)
476 {
477 int flags = 0;
478
479 if (!bgp_configured)
480 return 0;
481
482 if (peer->state == Disabled || peer->state == Idle)
483 return 0;
484
485 if (peer->inbuf->done < BGP_MAX_PACKET_SIZE)
486 flags |= 1;
487
488 if (peer->state == Connect || /* connection in progress */
489 peer->update_routes || /* routing updates */
490 peer->outbuf->packet.header.len) /* pending output */
491 flags |= 2;
492
493 return flags;
494 }
495
496 /* process bgp peer */
497 int bgp_process(struct bgp_peer *peer, int readable, int writable)
498 {
499 if (!bgp_configured)
500 return 0;
501
502 if (*peer->name && peer->cli_flag == BGP_CLI_RESTART)
503 return bgp_restart(peer);
504
505 if (peer->state == Disabled)
506 return 1;
507
508 if (peer->cli_flag)
509 {
510 switch (peer->cli_flag)
511 {
512 case BGP_CLI_SUSPEND:
513 if (peer->routing)
514 {
515 peer->routing = 0;
516 if (peer->state == Established)
517 peer->update_routes = 1;
518 }
519
520 break;
521
522 case BGP_CLI_ENABLE:
523 if (!peer->routing)
524 {
525 peer->routing = 1;
526 if (peer->state == Established)
527 peer->update_routes = 1;
528 }
529
530 break;
531 }
532
533 peer->cli_flag = 0;
534 }
535
536 /* handle empty/fill of buffers */
537 if (writable)
538 {
539 int r = 1;
540 if (peer->state == Connect)
541 r = bgp_handle_connect(peer);
542 else if (peer->outbuf->packet.header.len)
543 r = bgp_write(peer);
544
545 if (!r)
546 return 0;
547 }
548
549 if (readable)
550 {
551 if (!bgp_read(peer))
552 return 0;
553 }
554
555 /* process input buffer contents */
556 while (peer->inbuf->done >= sizeof(peer->inbuf->packet.header)
557 && !peer->outbuf->packet.header.len) /* may need to queue a response */
558 {
559 if (bgp_handle_input(peer) < 0)
560 return 0;
561 }
562
563 /* process pending updates */
564 if (peer->update_routes
565 && !peer->outbuf->packet.header.len) /* ditto */
566 {
567 if (!bgp_send_update(peer))
568 return 0;
569 }
570
571 /* process timers */
572 if (peer->state == Established)
573 {
574 if (time_now > peer->expire_time)
575 {
576 log(1, 0, 0, 0, "No message from BGP peer %s in %ds\n",
577 peer->name, peer->hold);
578
579 bgp_send_notification(peer, BGP_ERR_HOLD_TIMER_EXP, 0);
580 return 0;
581 }
582
583 if (time_now > peer->keepalive_time && !peer->outbuf->packet.header.len)
584 bgp_send_keepalive(peer);
585 }
586 else if (peer->state == Idle)
587 {
588 if (time_now > peer->retry_time)
589 return bgp_connect(peer);
590 }
591 else if (time_now > peer->state_time + BGP_KEEPALIVE_TIME)
592 {
593 log(1, 0, 0, 0, "%s timer expired for BGP peer %s\n",
594 bgp_state_str(peer->state), peer->name);
595
596 return bgp_restart(peer);
597 }
598
599 return 1;
600 }
601
602 static void bgp_free_routes(struct bgp_route_list *routes)
603 {
604 struct bgp_route_list *tmp;
605
606 while ((tmp = routes))
607 {
608 routes = tmp->next;
609 free(tmp);
610 }
611 }
612
613 static char const *bgp_state_str(enum bgp_state state)
614 {
615 switch (state)
616 {
617 case Disabled: return "Disabled";
618 case Idle: return "Idle";
619 case Connect: return "Connect";
620 case Active: return "Active";
621 case OpenSent: return "OpenSent";
622 case OpenConfirm: return "OpenConfirm";
623 case Established: return "Established";
624 }
625
626 return "?";
627 }
628
629 static char const *bgp_msg_type_str(u8 type)
630 {
631 switch (type)
632 {
633 case BGP_MSG_OPEN: return "OPEN";
634 case BGP_MSG_UPDATE: return "UPDATE";
635 case BGP_MSG_NOTIFICATION: return "NOTIFICATION";
636 case BGP_MSG_KEEPALIVE: return "KEEPALIVE";
637 }
638
639 return "?";
640 }
641
642 /* attempt to connect to peer */
643 static int bgp_connect(struct bgp_peer *peer)
644 {
645 static int bgp_port = 0;
646 struct sockaddr_in addr;
647
648 if (!bgp_port)
649 {
650 struct servent *serv;
651 if (!(serv = getservbyname("bgp", "tcp")))
652 {
653 log(0, 0, 0, 0, "Can't get bgp service (%s)\n", strerror(errno));
654 return 0;
655 }
656
657 bgp_port = serv->s_port;
658 }
659
660 if ((peer->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
661 {
662 log(0, 0, 0, 0, "Can't create a socket for BGP peer %s (%s)\n",
663 peer->name, strerror(errno));
664
665 peer->state = peer->next_state = Disabled;
666 return 0;
667 }
668
669 /* set to non-blocking */
670 fcntl(peer->sock, F_SETFL, fcntl(peer->sock, F_GETFL, 0) | O_NONBLOCK);
671
672 /* try connect */
673 memset(&addr, 0, sizeof(addr));
674 addr.sin_family = AF_INET;
675 addr.sin_port = bgp_port;
676 addr.sin_addr.s_addr = peer->addr;
677
678 while (connect(peer->sock, (struct sockaddr *) &addr, sizeof(addr)) == -1)
679 {
680 if (errno == EINTR) /* SIGALARM handler */
681 continue;
682
683 if (errno != EINPROGRESS)
684 {
685 log(1, 0, 0, 0, "Can't connect to BGP peer %s (%s)\n",
686 inet_ntoa(addr.sin_addr), strerror(errno));
687
688 bgp_set_retry(peer);
689 return 0;
690 }
691
692 peer->state = Connect;
693 peer->state_time = time_now;
694
695 log(4, 0, 0, 0, "BGP peer %s: state Connect\n", peer->name);
696 return 1;
697 }
698
699 peer->state = Active;
700 peer->state_time = time_now;
701 peer->retry_time = peer->retry_count = 0;
702
703 log(4, 0, 0, 0, "BGP peer %s: state Active\n", inet_ntoa(addr.sin_addr));
704
705 return bgp_send_open(peer);
706 }
707
708 /* complete partial connection (state = Connect) */
709 static int bgp_handle_connect(struct bgp_peer *peer)
710 {
711 int err = 0;
712 int len = sizeof(int);
713 getsockopt(peer->sock, SOL_SOCKET, SO_ERROR, &err, &len);
714 if (err)
715 {
716 log(1, 0, 0, 0, "Can't connect to BGP peer %s (%s)\n", peer->name,
717 strerror(err));
718
719 bgp_set_retry(peer);
720 return 0;
721 }
722
723 peer->state = Active;
724 peer->state_time = time_now;
725
726 log(4, 0, 0, 0, "BGP peer %s: state Active\n", peer->name);
727
728 return bgp_send_open(peer);
729 }
730
731 /* initiate a write */
732 static int bgp_write(struct bgp_peer *peer)
733 {
734 int len = htons(peer->outbuf->packet.header.len);
735 int r;
736
737 while ((r = write(peer->sock, &peer->outbuf->packet + peer->outbuf->done,
738 len - peer->outbuf->done)) == -1)
739 {
740 if (errno == EINTR)
741 continue;
742
743 if (errno == EAGAIN)
744 return 1;
745
746 if (errno == EPIPE)
747 log(1, 0, 0, 0, "Connection to BGP peer %s closed\n", peer->name);
748 else
749 log(1, 0, 0, 0, "Can't write to BGP peer %s (%s)\n", peer->name,
750 strerror(errno));
751
752 bgp_set_retry(peer);
753 return 0;
754 }
755
756 if (r < len)
757 {
758 peer->outbuf->done += r;
759 return 1;
760 }
761
762 log(4, 0, 0, 0, "Sent %s to BGP peer %s\n",
763 bgp_msg_type_str(peer->outbuf->packet.header.type), peer->name);
764
765 peer->outbuf->packet.header.len = 0;
766 peer->outbuf->done = 0;
767
768 if (peer->state == Established)
769 peer->keepalive_time = time_now + BGP_KEEPALIVE_TIME;
770
771 if (peer->state != peer->next_state)
772 {
773 if (peer->next_state == Disabled || peer->next_state == Idle)
774 {
775 bgp_clear(peer);
776 return 0;
777 }
778
779 peer->state = peer->next_state;
780 peer->state_time = time_now;
781
782 log(4, 0, 0, 0, "BGP peer %s: state %s\n", peer->name,
783 bgp_state_str(peer->state));
784 }
785
786 return 1;
787 }
788
789 /* initiate a read */
790 static int bgp_read(struct bgp_peer *peer)
791 {
792 int r;
793
794 while ((r = read(peer->sock, &peer->inbuf->packet + peer->inbuf->done,
795 BGP_MAX_PACKET_SIZE - peer->inbuf->done)) < 1)
796 {
797 if (!r)
798 {
799 log(1, 0, 0, 0, "Connection to BGP peer %s closed\n", peer->name);
800 }
801 else
802 {
803 if (errno == EINTR)
804 continue;
805
806 if (errno == EAGAIN)
807 return 1;
808
809 log(1, 0, 0, 0, "Can't read from BGP peer %s (%s)\n", peer->name,
810 strerror(errno));
811 }
812
813 bgp_set_retry(peer);
814 return 0;
815 }
816
817 peer->inbuf->done += r;
818 return 1;
819 }
820
821 /* process buffered packets */
822 static int bgp_handle_input(struct bgp_peer *peer)
823 {
824 struct bgp_packet *p = &peer->inbuf->packet;
825 int len = ntohs(p->header.len);
826
827 if (len > BGP_MAX_PACKET_SIZE)
828 {
829 log(1, 0, 0, 0, "Bad header length from BGP %s\n", peer->name);
830 bgp_send_notification(peer, BGP_ERR_HEADER, BGP_ERR_HDR_BAD_LEN);
831 return 0;
832 }
833
834 if (peer->inbuf->done < len)
835 return 0;
836
837 log(4, 0, 0, 0, "Received %s from BGP peer %s\n",
838 bgp_msg_type_str(p->header.type), peer->name);
839
840 switch (p->header.type)
841 {
842 case BGP_MSG_OPEN:
843 {
844 struct bgp_data_open data;
845 int i;
846
847 for (i = 0; i < sizeof(p->header.marker); i++)
848 {
849 if ((unsigned char) p->header.marker[i] != 0xff)
850 {
851 log(1, 0, 0, 0, "Invalid marker from BGP peer %s\n",
852 peer->name);
853
854 bgp_send_notification(peer, BGP_ERR_HEADER,
855 BGP_ERR_HDR_NOT_SYNC);
856
857 return 0;
858 }
859 }
860
861 if (peer->state != OpenSent)
862 {
863 log(1, 0, 0, 0, "OPEN from BGP peer %s in %s state\n",
864 peer->name, bgp_state_str(peer->state));
865
866 bgp_send_notification(peer, BGP_ERR_FSM, 0);
867 return 0;
868 }
869
870 memcpy(&data, p->data, len - sizeof(p->header));
871
872 if (data.version != BGP_VERSION)
873 {
874 log(1, 0, 0, 0, "Bad version (%d) sent by BGP peer %s\n",
875 (int) data.version, peer->name);
876
877 bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_OPN_VERSION);
878 return 0;
879 }
880
881 if (ntohs(data.as) != peer->as)
882 {
883 log(1, 0, 0, 0, "Bad AS sent by BGP peer %s (got %d, "
884 "expected %d)\n", peer->name, (int) htons(data.as),
885 (int) peer->as);
886
887 bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_OPN_BAD_AS);
888 return 0;
889 }
890
891 if ((peer->hold = ntohs(data.hold_time)) < 10)
892 {
893 log(1, 0, 0, 0, "Bad hold time (%d) from BGP peer %s\n",
894 peer->hold, peer->name);
895
896 bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_OPN_HOLD_TIME);
897 return 0;
898 }
899
900 /* next transition requires an exchange of keepalives */
901 bgp_send_keepalive(peer);
902
903 /* FIXME: may need to check for optional params */
904 }
905
906 break;
907
908 case BGP_MSG_KEEPALIVE:
909 if (peer->state == OpenConfirm)
910 {
911 peer->state = peer->next_state = Established;
912 peer->state_time = time_now;
913 peer->keepalive_time = time_now + BGP_KEEPALIVE_TIME;
914 peer->update_routes = 1;
915 peer->retry_count = 0;
916 peer->retry_time = 0;
917
918 log(4, 0, 0, 0, "BGP peer %s: state Established\n", peer->name);
919 }
920
921 break;
922
923 case BGP_MSG_NOTIFICATION:
924 if (len > sizeof(p->header))
925 {
926 struct bgp_data_notification *notification =
927 (struct bgp_data_notification *) p->data;
928
929 if (notification->error_code == BGP_ERR_CEASE)
930 {
931 log(4, 0, 0, 0, "BGP peer %s sent CEASE\n", peer->name);
932 bgp_halt(peer);
933 return 0;
934 }
935
936 /* FIXME: should handle more notifications */
937 log(4, 0, 0, 0, "BGP peer %s sent unhandled NOTIFICATION %d\n",
938 peer->name, (int) notification->error_code);
939 }
940
941 break;
942 }
943
944 /* reset timer */
945 peer->expire_time = time_now + peer->hold;
946
947 /* see if there's another message in the same packet/buffer */
948 if (peer->inbuf->done > len)
949 {
950 peer->inbuf->done -= len;
951 memmove(p, (char *) p + len, peer->inbuf->done);
952 }
953 else
954 {
955 peer->inbuf->packet.header.len = 0;
956 peer->inbuf->done = 0;
957 }
958
959 return peer->inbuf->done;
960 }
961
962 /* send/buffer OPEN message */
963 static int bgp_send_open(struct bgp_peer *peer)
964 {
965 struct bgp_data_open data;
966 u16 len = sizeof(peer->outbuf->packet.header);
967
968 memset(peer->outbuf->packet.header.marker, 0xff,
969 sizeof(peer->outbuf->packet.header.marker));
970
971 peer->outbuf->packet.header.type = BGP_MSG_OPEN;
972
973 data.version = BGP_VERSION;
974 data.as = htons(our_as);
975 data.hold_time = htons(BGP_HOLD_TIME);
976 data.identifier = my_address;
977 data.opt_len = 0;
978
979 memcpy(peer->outbuf->packet.data, &data, BGP_DATA_OPEN_SIZE);
980 len += BGP_DATA_OPEN_SIZE;
981
982 peer->outbuf->packet.header.len = htons(len);
983 peer->outbuf->done = 0;
984 peer->next_state = OpenSent;
985
986 return bgp_write(peer);
987 }
988
989 /* send/buffer KEEPALIVE message */
990 static int bgp_send_keepalive(struct bgp_peer *peer)
991 {
992 memset(peer->outbuf->packet.header.marker, 0xff,
993 sizeof(peer->outbuf->packet.header.marker));
994
995 peer->outbuf->packet.header.type = BGP_MSG_KEEPALIVE;
996 peer->outbuf->packet.header.len =
997 htons(sizeof(peer->outbuf->packet.header));
998
999 peer->outbuf->done = 0;
1000 peer->next_state = (peer->state == OpenSent) ? OpenConfirm : peer->state;
1001
1002 return bgp_write(peer);
1003 }
1004
1005 /* send/buffer UPDATE message */
1006 static int bgp_send_update(struct bgp_peer *peer)
1007 {
1008 u16 unf_len = 0;
1009 u16 attr_len;
1010 u16 len = sizeof(peer->outbuf->packet.header);
1011 struct bgp_route_list *have = peer->routes;
1012 struct bgp_route_list *want = peer->routing ? bgp_routes : 0;
1013 struct bgp_route_list *e = 0;
1014 struct bgp_route_list *add = 0;
1015 int s;
1016
1017 char *data = (char *) &peer->outbuf->packet.data;
1018
1019 /* need leave room for attr_len, bgp_path_attrs and one prefix */
1020 char *max = (char *) &peer->outbuf->packet.data
1021 + sizeof(peer->outbuf->packet.data)
1022 - sizeof(attr_len) - peer->path_attr_len - sizeof(struct bgp_ip_prefix);
1023
1024 /* skip over unf_len */
1025 data += sizeof(unf_len);
1026 len += sizeof(unf_len);
1027
1028 memset(peer->outbuf->packet.header.marker, 0xff,
1029 sizeof(peer->outbuf->packet.header.marker));
1030
1031 peer->outbuf->packet.header.type = BGP_MSG_UPDATE;
1032
1033 peer->update_routes = 0; /* tentatively clear */
1034
1035 /* find differences */
1036 while ((have || want) && data < (max - sizeof(struct bgp_ip_prefix)))
1037 {
1038 if (have)
1039 s = want
1040 ? memcmp(&have->dest, &want->dest, sizeof(have->dest))
1041 : -1;
1042 else
1043 s = 1;
1044
1045 if (s < 0) /* found one to delete */
1046 {
1047 struct bgp_route_list *tmp = have;
1048 have = have->next;
1049
1050 s = BGP_IP_PREFIX_SIZE(tmp->dest);
1051 memcpy(data, &tmp->dest, s);
1052 data += s;
1053 unf_len += s;
1054 len += s;
1055
1056 log(5, 0, 0, 0, "Withdrawing route %s/%d from BGP peer %s\n",
1057 inet_toa(tmp->dest.prefix), tmp->dest.len, peer->name);
1058
1059 free(tmp);
1060
1061 if (e)
1062 e->next = have;
1063 else
1064 peer->routes = have;
1065 }
1066 else
1067 {
1068 if (!s) /* same */
1069 {
1070 e = have; /* stash the last found to relink above */
1071 have = have->next;
1072 want = want->next;
1073 }
1074 else if (s > 0) /* addition reqd. */
1075 {
1076 if (add)
1077 {
1078 peer->update_routes = 1; /* only one add per packet */
1079 if (!have)
1080 break;
1081 }
1082 else
1083 add = want;
1084
1085 if (want)
1086 want = want->next;
1087 }
1088 }
1089 }
1090
1091 if (have || want)
1092 peer->update_routes = 1; /* more to do */
1093
1094 /* anything changed? */
1095 if (!(unf_len || add))
1096 return 1;
1097
1098 /* go back and insert unf_len */
1099 unf_len = htons(unf_len);
1100 memcpy(&peer->outbuf->packet.data, &unf_len, sizeof(unf_len));
1101
1102 if (add)
1103 {
1104 if (!(e = malloc(sizeof(*e))))
1105 {
1106 log(0, 0, 0, 0, "Can't allocate route for %s/%d (%s)\n",
1107 inet_toa(add->dest.prefix), add->dest.len, strerror(errno));
1108
1109 return 0;
1110 }
1111
1112 memcpy(e, add, sizeof(*e));
1113 e->next = 0;
1114 peer->routes = bgp_insert_route(peer->routes, e);
1115
1116 attr_len = htons(peer->path_attr_len);
1117 memcpy(data, &attr_len, sizeof(attr_len));
1118 data += sizeof(attr_len);
1119 len += sizeof(attr_len);
1120
1121 memcpy(data, peer->path_attrs, peer->path_attr_len);
1122 data += peer->path_attr_len;
1123 len += peer->path_attr_len;
1124
1125 s = BGP_IP_PREFIX_SIZE(add->dest);
1126 memcpy(data, &add->dest, s);
1127 data += s;
1128 len += s;
1129
1130 log(5, 0, 0, 0, "Advertising route %s/%d to BGP peer %s\n",
1131 inet_toa(add->dest.prefix), add->dest.len, peer->name);
1132 }
1133 else
1134 {
1135 attr_len = 0;
1136 memcpy(data, &attr_len, sizeof(attr_len));
1137 data += sizeof(attr_len);
1138 len += sizeof(attr_len);
1139 }
1140
1141 peer->outbuf->packet.header.len = htons(len);
1142 peer->outbuf->done = 0;
1143
1144 return bgp_write(peer);
1145 }
1146
1147 /* send/buffer NOTIFICATION message */
1148 static int bgp_send_notification(struct bgp_peer *peer, u8 code, u8 subcode)
1149 {
1150 struct bgp_data_notification data;
1151 u16 len = 0;
1152
1153 data.error_code = code;
1154 len += sizeof(data.error_code);
1155
1156 data.error_subcode = subcode;
1157 len += sizeof(data.error_code);
1158
1159 memset(peer->outbuf->packet.header.marker, 0xff,
1160 sizeof(peer->outbuf->packet.header.marker));
1161
1162 peer->outbuf->packet.header.type = BGP_MSG_NOTIFICATION;
1163 peer->outbuf->packet.header.len =
1164 htons(sizeof(peer->outbuf->packet.header) + len);
1165
1166 memcpy(peer->outbuf->packet.data, &data, len);
1167
1168 peer->outbuf->done = 0;
1169 peer->next_state = code == BGP_ERR_CEASE ? Disabled : Idle;
1170
1171 /* we're dying; ignore any pending input */
1172 peer->inbuf->packet.header.len = 0;
1173 peer->inbuf->done = 0;
1174
1175 return bgp_write(peer);
1176 }
1177
1178 /* CLI stuff */
1179
1180 #include <libcli.h>
1181
1182 int cmd_show_bgp(struct cli_def *cli, char *command, char **argv, int argc)
1183 {
1184 int i;
1185 int hdr = 0;
1186 char *addr;
1187
1188 if (!bgp_configured)
1189 return CLI_OK;
1190
1191 if (CLI_HELP_REQUESTED)
1192 return cli_arg_help(cli, 1,
1193 "A.B.C.D", "BGP peer address",
1194 "NAME", "BGP peer name",
1195 NULL);
1196
1197 cli_print(cli, "BGPv%d router identifier %s, local AS number %d, "
1198 "hold time %ds", BGP_VERSION, inet_toa(my_address), (int) our_as,
1199 BGP_HOLD_TIME);
1200
1201 time(&time_now);
1202
1203 for (i = 0; i < BGP_NUM_PEERS; i++)
1204 {
1205 if (!*bgp_peers[i].name)
1206 continue;
1207
1208 addr = inet_toa(bgp_peers[i].addr);
1209 if (argc && strcmp(addr, argv[0]) &&
1210 strncmp(bgp_peers[i].name, argv[0], strlen(argv[0])))
1211 continue;
1212
1213 if (!hdr++)
1214 {
1215 cli_print(cli, "");
1216 cli_print(cli, "Peer AS Address "
1217 "State Retries Retry in Route Pend");
1218 cli_print(cli, "------------------ ----- --------------- "
1219 "----------- ------- -------- ----- ----");
1220 }
1221
1222 cli_print(cli, "%-18.18s %5d %15s %-11s %7d %7ds %5s %4s",
1223 bgp_peers[i].name,
1224 bgp_peers[i].as,
1225 addr,
1226 bgp_state_str(bgp_peers[i].state),
1227 bgp_peers[i].retry_count,
1228 bgp_peers[i].retry_time ? bgp_peers[i].retry_time - time_now : 0,
1229 bgp_peers[i].routing ? "yes" : "no",
1230 bgp_peers[i].update_routes ? "yes" : "no");
1231 }
1232
1233 return CLI_OK;
1234 }
1235
1236 int cmd_suspend_bgp(struct cli_def *cli, char *command, char **argv, int argc)
1237 {
1238 int i;
1239 char *addr;
1240
1241 if (!bgp_configured)
1242 return CLI_OK;
1243
1244 if (CLI_HELP_REQUESTED)
1245 return cli_arg_help(cli, 1,
1246 "A.B.C.D", "BGP peer address",
1247 "NAME", "BGP peer name",
1248 NULL);
1249
1250 for (i = 0; i < BGP_NUM_PEERS; i++)
1251 {
1252 if (bgp_peers[i].state != Established)
1253 continue;
1254
1255 if (!bgp_peers[i].routing)
1256 continue;
1257
1258 addr = inet_toa(bgp_peers[i].addr);
1259 if (argc && strcmp(addr, argv[0]) && strcmp(bgp_peers[i].name, argv[0]))
1260 continue;
1261
1262 bgp_peers[i].cli_flag = BGP_CLI_SUSPEND;
1263 cli_print(cli, "Suspending peer %s", bgp_peers[i].name);
1264 }
1265
1266 return CLI_OK;
1267 }
1268
1269 int cmd_no_suspend_bgp(struct cli_def *cli, char *command, char **argv, int argc)
1270 {
1271 int i;
1272 char *addr;
1273
1274 if (!bgp_configured)
1275 return CLI_OK;
1276
1277 if (CLI_HELP_REQUESTED)
1278 return cli_arg_help(cli, 1,
1279 "A.B.C.D", "BGP peer address",
1280 "NAME", "BGP peer name",
1281 NULL);
1282
1283 for (i = 0; i < BGP_NUM_PEERS; i++)
1284 {
1285 if (bgp_peers[i].state != Established)
1286 continue;
1287
1288 if (bgp_peers[i].routing)
1289 continue;
1290
1291 addr = inet_toa(bgp_peers[i].addr);
1292 if (argc && strcmp(addr, argv[0]) &&
1293 strncmp(bgp_peers[i].name, argv[0], strlen(argv[0])))
1294 continue;
1295
1296 bgp_peers[i].cli_flag = BGP_CLI_ENABLE;
1297 cli_print(cli, "Un-suspending peer %s", bgp_peers[i].name);
1298 }
1299
1300 return CLI_OK;
1301 }
1302
1303 int cmd_restart_bgp(struct cli_def *cli, char *command, char **argv, int argc)
1304 {
1305 int i;
1306 char *addr;
1307
1308 if (!bgp_configured)
1309 return CLI_OK;
1310
1311 if (CLI_HELP_REQUESTED)
1312 return cli_arg_help(cli, 1,
1313 "A.B.C.D", "BGP peer address",
1314 "NAME", "BGP peer name",
1315 NULL);
1316
1317 for (i = 0; i < BGP_NUM_PEERS; i++)
1318 {
1319 if (!*bgp_peers[i].name)
1320 continue;
1321
1322 addr = inet_toa(bgp_peers[i].addr);
1323 if (argc && strcmp(addr, argv[0]) &&
1324 strncmp(bgp_peers[i].name, argv[0], strlen(argv[0])))
1325 continue;
1326
1327 bgp_peers[i].cli_flag = BGP_CLI_RESTART;
1328 cli_print(cli, "Restarting peer %s", bgp_peers[i].name);
1329 }
1330
1331 return CLI_OK;
1332 }