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