d9c581874741792569fbe3d9eaa0ac2bbc14699b
[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.12 2005/09/02 23:39:36 bodea 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 static struct bgp_route6_list *bgp_insert_route6(struct bgp_route6_list *head,
36 struct bgp_route6_list *new);
37
38 static void bgp_free_routes(struct bgp_route_list *routes);
39 static void bgp_free_routes6(struct bgp_route6_list *routes);
40 static char const *bgp_msg_type_str(uint8_t type);
41 static int bgp_connect(struct bgp_peer *peer);
42 static int bgp_handle_connect(struct bgp_peer *peer);
43 static int bgp_write(struct bgp_peer *peer);
44 static int bgp_read(struct bgp_peer *peer);
45 static int bgp_handle_input(struct bgp_peer *peer);
46 static int bgp_send_open(struct bgp_peer *peer);
47 static int bgp_send_keepalive(struct bgp_peer *peer);
48 static int bgp_send_update(struct bgp_peer *peer);
49 static int bgp_send_update6(struct bgp_peer *peer);
50 static int bgp_send_notification(struct bgp_peer *peer, uint8_t code,
51 uint8_t subcode);
52 static int bgp_send_notification_full(struct bgp_peer *peer, uint8_t code,
53 uint8_t subcode, char *notification_data, uint16_t data_len);
54
55 static uint16_t our_as;
56 static struct bgp_route_list *bgp_routes = 0;
57 static struct bgp_route6_list *bgp_routes6 = 0;
58
59 int bgp_configured = 0;
60 struct bgp_peer *bgp_peers = 0;
61
62 /* prepare peer structure, globals */
63 int bgp_setup(int as)
64 {
65 int i;
66 struct bgp_peer *peer;
67
68 for (i = 0; i < BGP_NUM_PEERS; i++)
69 {
70 peer = &bgp_peers[i];
71 memset(peer, 0, sizeof(*peer));
72
73 peer->addr = INADDR_NONE;
74 peer->sock = -1;
75 peer->state = peer->next_state = Disabled;
76
77 if (!((peer->outbuf = malloc(sizeof(*peer->outbuf)))
78 && (peer->inbuf = malloc(sizeof(*peer->inbuf)))))
79 {
80 LOG(0, 0, 0, "Can't allocate buffers for bgp peer (%s)\n",
81 strerror(errno));
82
83 return 0;
84 }
85
86 peer->edata.type = FD_TYPE_BGP;
87 peer->edata.index = i;
88 peer->events = 0;
89 }
90
91 if (as < 1)
92 as = 0;
93
94 if ((our_as = as))
95 return 0;
96
97 bgp_routes = 0;
98 bgp_routes6 = 0;
99 bgp_configured = 0; /* set by bgp_start */
100
101 return 1;
102 }
103
104 /* start connection with a peer */
105 int bgp_start(struct bgp_peer *peer, char *name, int as, int keepalive,
106 int hold, int enable)
107 {
108 struct hostent *h;
109 int ibgp;
110 int i;
111 struct bgp_path_attr a;
112 char path_attrs[64];
113 char *p = path_attrs;
114 in_addr_t ip;
115 uint32_t metric = htonl(BGP_METRIC);
116 uint32_t no_export = htonl(BGP_COMMUNITY_NO_EXPORT);
117
118 if (!our_as)
119 return 0;
120
121 if (peer->state != Disabled)
122 bgp_halt(peer);
123
124 snprintf(peer->name, sizeof(peer->name), "%s", name);
125
126 if (!(h = gethostbyname(name)) || h->h_addrtype != AF_INET)
127 {
128 LOG(0, 0, 0, "Can't get address for BGP peer %s (%s)\n",
129 name, h ? "no address" : hstrerror(h_errno));
130
131 return 0;
132 }
133
134 memcpy(&peer->addr, h->h_addr, sizeof(peer->addr));
135 peer->as = as > 0 ? as : our_as;
136 ibgp = peer->as == our_as;
137
138 /* set initial timer values */
139 peer->init_keepalive = keepalive == -1 ? BGP_KEEPALIVE_TIME : keepalive;
140 peer->init_hold = hold == -1 ? BGP_HOLD_TIME : hold;
141
142 if (peer->init_hold < 3)
143 peer->init_hold = 3;
144
145 if (peer->init_keepalive * 3 > peer->init_hold)
146 peer->init_keepalive = peer->init_hold / 3;
147
148 /* clear buffers, go to Idle state */
149 peer->next_state = Idle;
150 bgp_clear(peer);
151
152 /* set initial routing state */
153 peer->routing = enable;
154
155 /* all our routes use the same attributes, so prepare it in advance */
156 if (peer->path_attrs)
157 free(peer->path_attrs);
158
159 peer->path_attr_len = 0;
160
161 /* ORIGIN */
162 a.flags = BGP_PATH_ATTR_FLAG_TRANS;
163 a.code = BGP_PATH_ATTR_CODE_ORIGIN;
164 a.data.s.len = 1;
165 a.data.s.value[0] = BGP_PATH_ATTR_CODE_ORIGIN_IGP;
166
167 #define ADD_ATTRIBUTE() do { \
168 i = BGP_PATH_ATTR_SIZE(a); \
169 memcpy(p, &a, i); \
170 p += i; \
171 peer->path_attr_len += i; } while (0)
172
173 ADD_ATTRIBUTE();
174
175 /* AS_PATH */
176 a.flags = BGP_PATH_ATTR_FLAG_TRANS;
177 a.code = BGP_PATH_ATTR_CODE_AS_PATH;
178 if (ibgp)
179 {
180 /* empty path */
181 a.data.s.len = 0;
182 }
183 else
184 {
185 /* just our AS */
186 struct {
187 uint8_t type;
188 uint8_t len;
189 uint16_t value;
190 } as_path = {
191 BGP_PATH_ATTR_CODE_AS_PATH_AS_SEQUENCE,
192 1,
193 htons(our_as),
194 };
195
196 a.data.s.len = sizeof(as_path);
197 memcpy(&a.data.s.value, &as_path, sizeof(as_path));
198 }
199
200 ADD_ATTRIBUTE();
201
202 /* MULTI_EXIT_DISC */
203 a.flags = BGP_PATH_ATTR_FLAG_OPTIONAL;
204 a.code = BGP_PATH_ATTR_CODE_MULTI_EXIT_DISC;
205 a.data.s.len = sizeof(metric);
206 memcpy(a.data.s.value, &metric, sizeof(metric));
207
208 ADD_ATTRIBUTE();
209
210 if (ibgp)
211 {
212 uint32_t local_pref = htonl(BGP_LOCAL_PREF);
213
214 /* LOCAL_PREF */
215 a.flags = BGP_PATH_ATTR_FLAG_TRANS;
216 a.code = BGP_PATH_ATTR_CODE_LOCAL_PREF;
217 a.data.s.len = sizeof(local_pref);
218 memcpy(a.data.s.value, &local_pref, sizeof(local_pref));
219
220 ADD_ATTRIBUTE();
221 }
222
223 /* COMMUNITIES */
224 a.flags = BGP_PATH_ATTR_FLAG_OPTIONAL | BGP_PATH_ATTR_FLAG_TRANS;
225 a.code = BGP_PATH_ATTR_CODE_COMMUNITIES;
226 a.data.s.len = sizeof(no_export);
227 memcpy(a.data.s.value, &no_export, sizeof(no_export));
228
229 ADD_ATTRIBUTE();
230
231 /* remember the len before adding NEXT_HOP */
232 peer->path_attr_len_without_nexthop = peer->path_attr_len;
233
234 /* NEXT_HOP */
235 a.flags = BGP_PATH_ATTR_FLAG_TRANS;
236 a.code = BGP_PATH_ATTR_CODE_NEXT_HOP;
237 ip = my_address; /* we're it */
238 a.data.s.len = sizeof(ip);
239 memcpy(a.data.s.value, &ip, sizeof(ip));
240
241 ADD_ATTRIBUTE();
242
243 if (!(peer->path_attrs = malloc(peer->path_attr_len)))
244 {
245 LOG(0, 0, 0, "Can't allocate path_attrs for %s (%s)\n",
246 name, strerror(errno));
247
248 return 0;
249 }
250
251 memcpy(peer->path_attrs, path_attrs, peer->path_attr_len);
252
253 /* multiprotocol attributes initialization */
254 if (config->ipv6_prefix.s6_addr[0])
255 {
256 struct bgp_attr_mp_reach_nlri_partial mp_reach_nlri_partial;
257 struct bgp_attr_mp_unreach_nlri_partial mp_unreach_nlri_partial;
258
259 a.flags = BGP_PATH_ATTR_FLAG_OPTIONAL;
260 a.code = BGP_PATH_ATTR_CODE_MP_REACH_NLRI;
261 a.data.s.len = 0; /* will be set on UPDATE */
262
263 mp_reach_nlri_partial.afi = htons(AF_INET6);
264 mp_reach_nlri_partial.safi = BGP_MP_SAFI_UNICAST;
265 mp_reach_nlri_partial.reserved = 0;
266 mp_reach_nlri_partial.next_hop_len = 16;
267
268 /* use the defined nexthop6, or our address in ipv6_prefix */
269 if (config->nexthop6_address.s6_addr[0])
270 memcpy(&mp_reach_nlri_partial.next_hop,
271 &config->nexthop6_address.s6_addr, 16);
272 else
273 {
274 /* our address is ipv6prefix::1 */
275 memcpy(&mp_reach_nlri_partial.next_hop,
276 &config->ipv6_prefix.s6_addr, 16);
277 mp_reach_nlri_partial.next_hop[15] = 1;
278 }
279
280 memcpy(&a.data.s.value, &mp_reach_nlri_partial,
281 sizeof(struct bgp_attr_mp_reach_nlri_partial));
282 memcpy(&peer->mp_reach_nlri_partial, &a,
283 BGP_PATH_ATTR_MP_REACH_NLRI_PARTIAL_SIZE);
284
285 a.flags = BGP_PATH_ATTR_FLAG_OPTIONAL | BGP_PATH_ATTR_FLAG_EXTLEN;
286 a.code = BGP_PATH_ATTR_CODE_MP_UNREACH_NLRI;
287 a.data.e.len = 0; /* will be set on UPDATE */
288
289 mp_unreach_nlri_partial.afi = htons(AF_INET6);
290 mp_unreach_nlri_partial.safi = BGP_MP_SAFI_UNICAST;
291
292 memcpy(&a.data.e.value, &mp_unreach_nlri_partial,
293 sizeof(struct bgp_attr_mp_unreach_nlri_partial));
294 memcpy(&peer->mp_unreach_nlri_partial, &a,
295 BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE);
296 }
297
298 LOG(4, 0, 0, "Initiating BGP connection to %s (routing %s)\n",
299 name, enable ? "enabled" : "suspended");
300
301 /* we have at least one peer configured */
302 bgp_configured = 1;
303
304 /* connect */
305 return bgp_connect(peer);
306 }
307
308 /* clear counters, timers, routes and buffers; close socket; move to
309 next_state, which may be Disabled or Idle */
310 static void bgp_clear(struct bgp_peer *peer)
311 {
312 if (peer->sock != -1)
313 {
314 close(peer->sock);
315 peer->sock = -1;
316 }
317
318 peer->keepalive_time = 0;
319 peer->expire_time = 0;
320
321 peer->keepalive = peer->init_keepalive;
322 peer->hold = peer->init_hold;
323
324 bgp_free_routes(peer->routes);
325 peer->routes = 0;
326 bgp_free_routes6(peer->routes6);
327 peer->routes6 = 0;
328
329 peer->outbuf->packet.header.len = 0;
330 peer->outbuf->done = 0;
331 peer->inbuf->packet.header.len = 0;
332 peer->inbuf->done = 0;
333
334 peer->cli_flag = 0;
335 peer->events = 0;
336
337 if (peer->state != peer->next_state)
338 {
339 peer->state = peer->next_state;
340 peer->state_time = time_now;
341
342 LOG(4, 0, 0, "BGP peer %s: state %s\n", peer->name,
343 bgp_state_str(peer->next_state));
344 }
345 }
346
347 /* initiate a clean shutdown */
348 void bgp_stop(struct bgp_peer *peer)
349 {
350 LOG(4, 0, 0, "Terminating BGP connection to %s\n", peer->name);
351 bgp_send_notification(peer, BGP_ERR_CEASE, 0);
352 }
353
354 /* drop connection (if any) and set state to Disabled */
355 void bgp_halt(struct bgp_peer *peer)
356 {
357 LOG(4, 0, 0, "Aborting BGP connection to %s\n", peer->name);
358 peer->next_state = Disabled;
359 bgp_clear(peer);
360 }
361
362 /* drop connection (if any) and set to Idle for connection retry */
363 int bgp_restart(struct bgp_peer *peer)
364 {
365 peer->next_state = Idle;
366 bgp_clear(peer);
367
368 /* restart now */
369 peer->retry_time = time_now;
370 peer->retry_count = 0;
371
372 /* connect */
373 return bgp_connect(peer);
374 }
375
376 static void bgp_set_retry(struct bgp_peer *peer)
377 {
378 if (peer->retry_count++ < BGP_MAX_RETRY)
379 {
380 peer->retry_time = time_now + (BGP_RETRY_BACKOFF * peer->retry_count);
381 peer->next_state = Idle;
382 bgp_clear(peer);
383 }
384 else
385 bgp_halt(peer); /* give up */
386 }
387
388 /* convert ip/mask to CIDR notation */
389 static void bgp_cidr(in_addr_t ip, in_addr_t mask, struct bgp_ip_prefix *pfx)
390 {
391 int i;
392 uint32_t b;
393
394 /* convert to prefix notation */
395 pfx->len = 32;
396 pfx->prefix = ip;
397
398 if (!mask) /* bogus */
399 mask = 0xffffffff;
400
401 for (i = 0; i < 32 && ((b = ntohl(1 << i)), !(mask & b)); i++)
402 {
403 pfx->len--;
404 pfx->prefix &= ~b;
405 }
406 }
407
408 /* insert route into list; sorted */
409 static struct bgp_route_list *bgp_insert_route(struct bgp_route_list *head,
410 struct bgp_route_list *new)
411 {
412 struct bgp_route_list *p = head;
413 struct bgp_route_list *e = 0;
414
415 while (p && memcmp(&p->dest, &new->dest, sizeof(p->dest)) < 0)
416 {
417 e = p;
418 p = p->next;
419 }
420
421 if (e)
422 {
423 new->next = e->next;
424 e->next = new;
425 }
426 else
427 {
428 new->next = head;
429 head = new;
430 }
431
432 return head;
433 }
434
435 /* insert route6 into list; sorted */
436 static struct bgp_route6_list *bgp_insert_route6(struct bgp_route6_list *head,
437 struct bgp_route6_list *new)
438 {
439 struct bgp_route6_list *p = head;
440 struct bgp_route6_list *e = 0;
441
442 while (p && memcmp(&p->dest, &new->dest, sizeof(p->dest)) < 0)
443 {
444 e = p;
445 p = p->next;
446 }
447
448 if (e)
449 {
450 new->next = e->next;
451 e->next = new;
452 }
453 else
454 {
455 new->next = head;
456 head = new;
457 }
458
459 return head;
460 }
461
462 /* add route to list for peers */
463 /*
464 * Note: this doesn't do route aggregation, nor drop routes if a less
465 * specific match already exists (partly because I'm lazy, but also so
466 * that if that route is later deleted we don't have to be concerned
467 * about adding back the more specific one).
468 */
469 int bgp_add_route(in_addr_t ip, in_addr_t mask)
470 {
471 struct bgp_route_list *r = bgp_routes;
472 struct bgp_route_list add;
473 int i;
474
475 bgp_cidr(ip, mask, &add.dest);
476 add.next = 0;
477
478 /* check for duplicate */
479 while (r)
480 {
481 i = memcmp(&r->dest, &add.dest, sizeof(r->dest));
482 if (!i)
483 return 1; /* already covered */
484
485 if (i > 0)
486 break;
487
488 r = r->next;
489 }
490
491 /* insert into route list; sorted */
492 if (!(r = malloc(sizeof(*r))))
493 {
494 LOG(0, 0, 0, "Can't allocate route for %s/%d (%s)\n",
495 fmtaddr(add.dest.prefix, 0), add.dest.len, strerror(errno));
496
497 return 0;
498 }
499
500 memcpy(r, &add, sizeof(*r));
501 bgp_routes = bgp_insert_route(bgp_routes, r);
502
503 /* flag established peers for update */
504 for (i = 0; i < BGP_NUM_PEERS; i++)
505 if (bgp_peers[i].state == Established)
506 bgp_peers[i].update_routes = 1;
507
508 LOG(4, 0, 0, "Registered BGP route %s/%d\n",
509 fmtaddr(add.dest.prefix, 0), add.dest.len);
510
511 return 1;
512 }
513
514 /* add route to list for peers */
515 /*
516 * Note: same provisions as above
517 */
518 int bgp_add_route6(struct in6_addr ip, int prefixlen)
519 {
520 struct bgp_route6_list *r = bgp_routes6;
521 struct bgp_route6_list add;
522 int i;
523 char ipv6addr[INET6_ADDRSTRLEN];
524
525 memcpy(&add.dest.prefix, &ip.s6_addr, 16);
526 add.dest.len = prefixlen;
527 add.next = 0;
528
529 /* check for duplicate */
530 while (r)
531 {
532 i = memcmp(&r->dest, &add.dest, sizeof(r->dest));
533 if (!i)
534 return 1; /* already covered */
535
536 if (i > 0)
537 break;
538
539 r = r->next;
540 }
541
542 /* insert into route list; sorted */
543 if (!(r = malloc(sizeof(*r))))
544 {
545 LOG(0, 0, 0, "Can't allocate route for %s/%d (%s)\n",
546 inet_ntop(AF_INET6, &ip, ipv6addr, INET6_ADDRSTRLEN), add.dest.len,
547 strerror(errno));
548
549 return 0;
550 }
551
552 memcpy(r, &add, sizeof(*r));
553 bgp_routes6 = bgp_insert_route6(bgp_routes6, r);
554
555 /* flag established peers for update */
556 for (i = 0; i < BGP_NUM_PEERS; i++)
557 if (bgp_peers[i].state == Established)
558 bgp_peers[i].update_routes6 = 1;
559
560 LOG(4, 0, 0, "Registered BGP route %s/%d\n",
561 inet_ntop(AF_INET6, &ip, ipv6addr, INET6_ADDRSTRLEN), add.dest.len);
562
563 return 1;
564 }
565
566 /* remove route from list for peers */
567 int bgp_del_route(in_addr_t ip, in_addr_t mask)
568 {
569 struct bgp_route_list *r = bgp_routes;
570 struct bgp_route_list *e = 0;
571 struct bgp_route_list del;
572 int i;
573
574 bgp_cidr(ip, mask, &del.dest);
575 del.next = 0;
576
577 /* find entry in routes list and remove */
578 while (r)
579 {
580 i = memcmp(&r->dest, &del.dest, sizeof(r->dest));
581 if (!i)
582 {
583 if (e)
584 e->next = r->next;
585 else
586 bgp_routes = r->next;
587
588 free(r);
589 break;
590 }
591
592 e = r;
593
594 if (i > 0)
595 r = 0; /* stop */
596 else
597 r = r->next;
598 }
599
600 /* not found */
601 if (!r)
602 return 1;
603
604 /* flag established peers for update */
605 for (i = 0; i < BGP_NUM_PEERS; i++)
606 if (bgp_peers[i].state == Established)
607 bgp_peers[i].update_routes = 1;
608
609 LOG(4, 0, 0, "Removed BGP route %s/%d\n",
610 fmtaddr(del.dest.prefix, 0), del.dest.len);
611
612 return 1;
613 }
614
615 /* remove route from list for peers */
616 int bgp_del_route6(struct in6_addr ip, int prefixlen)
617 {
618 struct bgp_route6_list *r = bgp_routes6;
619 struct bgp_route6_list *e = 0;
620 struct bgp_route6_list del;
621 int i;
622 char ipv6addr[INET6_ADDRSTRLEN];
623
624 memcpy(&del.dest.prefix, &ip.s6_addr, 16);
625 del.dest.len = prefixlen;
626 del.next = 0;
627
628 /* find entry in routes list and remove */
629 while (r)
630 {
631 i = memcmp(&r->dest, &del.dest, sizeof(r->dest));
632 if (!i)
633 {
634 if (e)
635 e->next = r->next;
636 else
637 bgp_routes6 = r->next;
638
639 free(r);
640 break;
641 }
642
643 e = r;
644
645 if (i > 0)
646 r = 0; /* stop */
647 else
648 r = r->next;
649 }
650
651 /* not found */
652 if (!r)
653 return 1;
654
655 /* flag established peers for update */
656 for (i = 0; i < BGP_NUM_PEERS; i++)
657 if (bgp_peers[i].state == Established)
658 bgp_peers[i].update_routes6 = 1;
659
660 LOG(4, 0, 0, "Removed BGP route %s/%d\n",
661 inet_ntop(AF_INET6, &ip, ipv6addr, INET6_ADDRSTRLEN), del.dest.len);
662
663 return 1;
664 }
665
666 /* enable or disable routing */
667 void bgp_enable_routing(int enable)
668 {
669 int i;
670
671 for (i = 0; i < BGP_NUM_PEERS; i++)
672 {
673 bgp_peers[i].routing = enable;
674
675 /* flag established peers for update */
676 if (bgp_peers[i].state == Established)
677 bgp_peers[i].update_routes = 1;
678 }
679
680 LOG(4, 0, 0, "%s BGP routing\n", enable ? "Enabled" : "Suspended");
681 }
682
683 #ifdef HAVE_EPOLL
684 # include <sys/epoll.h>
685 #else
686 # include "fake_epoll.h"
687 #endif
688
689 /* return a bitmask of the events required to poll this peer's fd */
690 int bgp_set_poll()
691 {
692 int i;
693
694 if (!bgp_configured)
695 return 0;
696
697 for (i = 0; i < BGP_NUM_PEERS; i++)
698 {
699 struct bgp_peer *peer = &bgp_peers[i];
700 int events = 0;
701
702 if (peer->state == Disabled || peer->state == Idle)
703 continue;
704
705 if (peer->inbuf->done < BGP_MAX_PACKET_SIZE)
706 events |= EPOLLIN;
707
708 if (peer->state == Connect || /* connection in progress */
709 peer->update_routes || /* routing updates */
710 peer->outbuf->packet.header.len) /* pending output */
711 events |= EPOLLOUT;
712
713 if (peer->events != events)
714 {
715 struct epoll_event ev;
716
717 ev.events = peer->events = events;
718 ev.data.ptr = &peer->edata;
719 epoll_ctl(epollfd, EPOLL_CTL_MOD, peer->sock, &ev);
720 }
721 }
722
723 return 1;
724 }
725
726 /* process bgp events/timers */
727 int bgp_process(uint32_t events[])
728 {
729 int i;
730
731 if (!bgp_configured)
732 return 0;
733
734 for (i = 0; i < BGP_NUM_PEERS; i++)
735 {
736 struct bgp_peer *peer = &bgp_peers[i];
737
738 if (*peer->name && peer->cli_flag == BGP_CLI_RESTART)
739 {
740 bgp_restart(peer);
741 continue;
742 }
743
744 if (peer->state == Disabled)
745 continue;
746
747 if (peer->cli_flag)
748 {
749 switch (peer->cli_flag)
750 {
751 case BGP_CLI_SUSPEND:
752 if (peer->routing)
753 {
754 peer->routing = 0;
755 if (peer->state == Established)
756 peer->update_routes = 1;
757 }
758
759 break;
760
761 case BGP_CLI_ENABLE:
762 if (!peer->routing)
763 {
764 peer->routing = 1;
765 if (peer->state == Established)
766 peer->update_routes = 1;
767 }
768
769 break;
770 }
771
772 peer->cli_flag = 0;
773 }
774
775 /* handle empty/fill of buffers */
776 if (events[i] & EPOLLOUT)
777 {
778 int r = 1;
779 if (peer->state == Connect)
780 r = bgp_handle_connect(peer);
781 else if (peer->outbuf->packet.header.len)
782 r = bgp_write(peer);
783
784 if (!r)
785 continue;
786 }
787
788 if (events[i] & (EPOLLIN|EPOLLHUP))
789 {
790 if (!bgp_read(peer))
791 continue;
792 }
793
794 /* process input buffer contents */
795 while (peer->inbuf->done >= sizeof(peer->inbuf->packet.header)
796 && !peer->outbuf->packet.header.len) /* may need to queue a response */
797 {
798 if (bgp_handle_input(peer) < 0)
799 continue;
800 }
801
802 /* process pending updates */
803 if (peer->update_routes
804 && !peer->outbuf->packet.header.len) /* ditto */
805 {
806 if (!bgp_send_update(peer))
807 continue;
808 }
809
810 /* process pending IPv6 updates */
811 if (peer->update_routes6
812 && !peer->outbuf->packet.header.len) /* ditto */
813 {
814 if (!bgp_send_update6(peer))
815 continue;
816 }
817
818 /* process timers */
819 if (peer->state == Established)
820 {
821 if (time_now > peer->expire_time)
822 {
823 LOG(1, 0, 0, "No message from BGP peer %s in %ds\n",
824 peer->name, peer->hold);
825
826 bgp_send_notification(peer, BGP_ERR_HOLD_TIMER_EXP, 0);
827 continue;
828 }
829
830 if (time_now > peer->keepalive_time && !peer->outbuf->packet.header.len)
831 bgp_send_keepalive(peer);
832 }
833 else if (peer->state == Idle)
834 {
835 if (time_now > peer->retry_time)
836 bgp_connect(peer);
837 }
838 else if (time_now > peer->state_time + BGP_STATE_TIME)
839 {
840 LOG(1, 0, 0, "%s timer expired for BGP peer %s\n",
841 bgp_state_str(peer->state), peer->name);
842
843 bgp_restart(peer);
844 }
845 }
846
847 return 1;
848 }
849
850 static void bgp_free_routes(struct bgp_route_list *routes)
851 {
852 struct bgp_route_list *tmp;
853
854 while ((tmp = routes))
855 {
856 routes = tmp->next;
857 free(tmp);
858 }
859 }
860
861 static void bgp_free_routes6(struct bgp_route6_list *routes)
862 {
863 struct bgp_route6_list *tmp;
864
865 while ((tmp = routes))
866 {
867 routes = tmp->next;
868 free(tmp);
869 }
870 }
871
872 char const *bgp_state_str(enum bgp_state state)
873 {
874 switch (state)
875 {
876 case Disabled: return "Disabled";
877 case Idle: return "Idle";
878 case Connect: return "Connect";
879 case Active: return "Active";
880 case OpenSent: return "OpenSent";
881 case OpenConfirm: return "OpenConfirm";
882 case Established: return "Established";
883 }
884
885 return "?";
886 }
887
888 static char const *bgp_msg_type_str(uint8_t type)
889 {
890 switch (type)
891 {
892 case BGP_MSG_OPEN: return "OPEN";
893 case BGP_MSG_UPDATE: return "UPDATE";
894 case BGP_MSG_NOTIFICATION: return "NOTIFICATION";
895 case BGP_MSG_KEEPALIVE: return "KEEPALIVE";
896 }
897
898 return "?";
899 }
900
901 /* attempt to connect to peer */
902 static int bgp_connect(struct bgp_peer *peer)
903 {
904 static int bgp_port = 0;
905 struct sockaddr_in addr;
906 struct epoll_event ev;
907
908 if (!bgp_port)
909 {
910 struct servent *serv;
911 if (!(serv = getservbyname("bgp", "tcp")))
912 {
913 LOG(0, 0, 0, "Can't get bgp service (%s)\n", strerror(errno));
914 return 0;
915 }
916
917 bgp_port = serv->s_port;
918 }
919
920 if ((peer->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
921 {
922 LOG(0, 0, 0, "Can't create a socket for BGP peer %s (%s)\n",
923 peer->name, strerror(errno));
924
925 peer->state = peer->next_state = Disabled;
926 return 0;
927 }
928
929 /* add to poll set */
930 ev.events = peer->events = EPOLLOUT;
931 ev.data.ptr = &peer->edata;
932 epoll_ctl(epollfd, EPOLL_CTL_ADD, peer->sock, &ev);
933
934 /* set to non-blocking */
935 fcntl(peer->sock, F_SETFL, fcntl(peer->sock, F_GETFL, 0) | O_NONBLOCK);
936
937 /* try connect */
938 memset(&addr, 0, sizeof(addr));
939 addr.sin_family = AF_INET;
940 addr.sin_port = bgp_port;
941 addr.sin_addr.s_addr = peer->addr;
942
943 while (connect(peer->sock, (struct sockaddr *) &addr, sizeof(addr)) == -1)
944 {
945 if (errno == EINTR) /* SIGALARM handler */
946 continue;
947
948 if (errno != EINPROGRESS)
949 {
950 LOG(1, 0, 0, "Can't connect to BGP peer %s (%s)\n",
951 inet_ntoa(addr.sin_addr), strerror(errno));
952
953 bgp_set_retry(peer);
954 return 0;
955 }
956
957 peer->state = Connect;
958 peer->state_time = time_now;
959
960 LOG(4, 0, 0, "BGP peer %s: state Connect\n", peer->name);
961 return 1;
962 }
963
964 peer->state = Active;
965 peer->state_time = time_now;
966 peer->retry_time = peer->retry_count = 0;
967
968 LOG(4, 0, 0, "BGP peer %s: state Active\n", inet_ntoa(addr.sin_addr));
969
970 peer->handle_ipv6_routes = 0;
971
972 return bgp_send_open(peer);
973 }
974
975 /* complete partial connection (state = Connect) */
976 static int bgp_handle_connect(struct bgp_peer *peer)
977 {
978 int err = 0;
979 socklen_t len = sizeof(int);
980 getsockopt(peer->sock, SOL_SOCKET, SO_ERROR, &err, &len);
981 if (err)
982 {
983 LOG(1, 0, 0, "Can't connect to BGP peer %s (%s)\n", peer->name,
984 strerror(err));
985
986 bgp_set_retry(peer);
987 return 0;
988 }
989
990 peer->state = Active;
991 peer->state_time = time_now;
992
993 LOG(4, 0, 0, "BGP peer %s: state Active\n", peer->name);
994
995 peer->handle_ipv6_routes = 0;
996
997 return bgp_send_open(peer);
998 }
999
1000 /* initiate a write */
1001 static int bgp_write(struct bgp_peer *peer)
1002 {
1003 int len = htons(peer->outbuf->packet.header.len);
1004 int r;
1005
1006 while ((r = write(peer->sock, &peer->outbuf->packet + peer->outbuf->done,
1007 len - peer->outbuf->done)) == -1)
1008 {
1009 if (errno == EINTR)
1010 continue;
1011
1012 if (errno == EAGAIN)
1013 return 1;
1014
1015 if (errno == EPIPE)
1016 LOG(1, 0, 0, "Connection to BGP peer %s closed\n", peer->name);
1017 else
1018 LOG(1, 0, 0, "Can't write to BGP peer %s (%s)\n", peer->name,
1019 strerror(errno));
1020
1021 bgp_set_retry(peer);
1022 return 0;
1023 }
1024
1025 if (r < len)
1026 {
1027 peer->outbuf->done += r;
1028 return 1;
1029 }
1030
1031 LOG(4, 0, 0, "Sent %s to BGP peer %s\n",
1032 bgp_msg_type_str(peer->outbuf->packet.header.type), peer->name);
1033
1034 peer->outbuf->packet.header.len = 0;
1035 peer->outbuf->done = 0;
1036
1037 if (peer->state == Established)
1038 peer->keepalive_time = time_now + peer->keepalive;
1039
1040 if (peer->state != peer->next_state)
1041 {
1042 if (peer->next_state == Disabled || peer->next_state == Idle)
1043 {
1044 bgp_clear(peer);
1045 return 0;
1046 }
1047
1048 peer->state = peer->next_state;
1049 peer->state_time = time_now;
1050
1051 LOG(4, 0, 0, "BGP peer %s: state %s\n", peer->name,
1052 bgp_state_str(peer->state));
1053 }
1054
1055 return 1;
1056 }
1057
1058 /* initiate a read */
1059 static int bgp_read(struct bgp_peer *peer)
1060 {
1061 int r;
1062
1063 while ((r = read(peer->sock, &peer->inbuf->packet + peer->inbuf->done,
1064 BGP_MAX_PACKET_SIZE - peer->inbuf->done)) < 1)
1065 {
1066 if (!r)
1067 {
1068 LOG(1, 0, 0, "Connection to BGP peer %s closed\n", peer->name);
1069 }
1070 else
1071 {
1072 if (errno == EINTR)
1073 continue;
1074
1075 if (errno == EAGAIN)
1076 return 1;
1077
1078 LOG(1, 0, 0, "Can't read from BGP peer %s (%s)\n", peer->name,
1079 strerror(errno));
1080 }
1081
1082 bgp_set_retry(peer);
1083 return 0;
1084 }
1085
1086 peer->inbuf->done += r;
1087 return 1;
1088 }
1089
1090 /* process buffered packets */
1091 static int bgp_handle_input(struct bgp_peer *peer)
1092 {
1093 struct bgp_packet *p = &peer->inbuf->packet;
1094 int len = ntohs(p->header.len);
1095
1096 if (len > BGP_MAX_PACKET_SIZE)
1097 {
1098 LOG(1, 0, 0, "Bad header length from BGP %s\n", peer->name);
1099 bgp_send_notification(peer, BGP_ERR_HEADER, BGP_ERR_HDR_BAD_LEN);
1100 return 0;
1101 }
1102
1103 if (peer->inbuf->done < len)
1104 return 0;
1105
1106 LOG(4, 0, 0, "Received %s from BGP peer %s\n",
1107 bgp_msg_type_str(p->header.type), peer->name);
1108
1109 switch (p->header.type)
1110 {
1111 case BGP_MSG_OPEN:
1112 {
1113 struct bgp_data_open data;
1114 int hold;
1115 int i;
1116 off_t param_offset, capability_offset;
1117 struct bgp_opt_param *param;
1118 uint8_t capabilities_len;
1119 char *capabilities = NULL;
1120 struct bgp_capability *capability;
1121 struct bgp_mp_cap_param *mp_cap;
1122
1123 for (i = 0; i < sizeof(p->header.marker); i++)
1124 {
1125 if ((unsigned char) p->header.marker[i] != 0xff)
1126 {
1127 LOG(1, 0, 0, "Invalid marker from BGP peer %s\n",
1128 peer->name);
1129
1130 bgp_send_notification(peer, BGP_ERR_HEADER,
1131 BGP_ERR_HDR_NOT_SYNC);
1132
1133 return 0;
1134 }
1135 }
1136
1137 if (peer->state != OpenSent)
1138 {
1139 LOG(1, 0, 0, "OPEN from BGP peer %s in %s state\n",
1140 peer->name, bgp_state_str(peer->state));
1141
1142 bgp_send_notification(peer, BGP_ERR_FSM, 0);
1143 return 0;
1144 }
1145
1146 memcpy(&data, p->data, len - sizeof(p->header));
1147
1148 if (data.version != BGP_VERSION)
1149 {
1150 LOG(1, 0, 0, "Bad version (%d) sent by BGP peer %s\n",
1151 (int) data.version, peer->name);
1152
1153 bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_OPN_VERSION);
1154 return 0;
1155 }
1156
1157 if (ntohs(data.as) != peer->as)
1158 {
1159 LOG(1, 0, 0, "Bad AS sent by BGP peer %s (got %d, "
1160 "expected %d)\n", peer->name, (int) htons(data.as),
1161 (int) peer->as);
1162
1163 bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_OPN_BAD_AS);
1164 return 0;
1165 }
1166
1167 if ((hold = ntohs(data.hold_time)) < 3)
1168 {
1169 LOG(1, 0, 0, "Bad hold time (%d) from BGP peer %s\n",
1170 hold, peer->name);
1171
1172 bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_OPN_HOLD_TIME);
1173 return 0;
1174 }
1175
1176 /* pick lowest hold time */
1177 if (hold < peer->hold)
1178 peer->hold = hold;
1179
1180 /* adjust our keepalive based on negotiated hold value */
1181 if (peer->keepalive * 3 > peer->hold)
1182 peer->keepalive = peer->hold / 3;
1183
1184 /* check for optional parameters */
1185 /* 2 is for the size of type + len (both uint8_t) */
1186 for (param_offset = 0;
1187 param_offset < data.opt_len;
1188 param_offset += 2 + param->len)
1189 {
1190 param = (struct bgp_opt_param *)(&data.opt_params + param_offset);
1191
1192 /* sensible check */
1193 if (data.opt_len - param_offset < 2
1194 || param->len > data.opt_len - param_offset - 2)
1195 {
1196 LOG(1, 0, 0, "Malformed Optional Parameter list from BGP peer %s\n",
1197 peer->name);
1198
1199 bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_UNSPEC);
1200 return 0;
1201 }
1202
1203 /* we know only one parameter type */
1204 if (param->type != BGP_PARAM_TYPE_CAPABILITY)
1205 {
1206 LOG(1, 0, 0, "Unsupported Optional Parameter type %d from BGP peer %s\n",
1207 param->type, peer->name);
1208
1209 bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_OPN_UNSUP_PARAM);
1210 return 0;
1211 }
1212
1213 capabilities_len = param->len;
1214 capabilities = (char *)&param->value;
1215 }
1216
1217 /* look for BGP multiprotocol capability */
1218 if (capabilities)
1219 {
1220 for (capability_offset = 0;
1221 capability_offset < capabilities_len;
1222 capability_offset += 2 + capability->len)
1223 {
1224 capability = (struct bgp_capability *)(capabilities + capability_offset);
1225
1226 /* sensible check */
1227 if (capabilities_len - capability_offset < 2
1228 || capability->len > capabilities_len - capability_offset - 2)
1229 {
1230 LOG(1, 0, 0, "Malformed Capabilities list from BGP peer %s\n",
1231 peer->name);
1232
1233 bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_UNSPEC);
1234 return 0;
1235 }
1236
1237 /* we only know one capability code */
1238 if (capability->code != BGP_CAP_CODE_MP
1239 && capability->len != sizeof(struct bgp_mp_cap_param))
1240 {
1241 LOG(4, 0, 0, "Unsupported Capability code %d from BGP peer %s\n",
1242 capability->code, peer->name);
1243
1244 bgp_send_notification_full(peer, BGP_ERR_OPEN, BGP_ERR_OPN_UNSUP_CAP,
1245 (char *)capability, 2 + capability->len);
1246 /* we don't terminate, still; we just jump to the next one */
1247 continue;
1248 }
1249
1250 mp_cap = (struct bgp_mp_cap_param *)&capability->value;
1251 /* the only <AFI, SAFI> tuple we support */
1252 if (ntohs(mp_cap->afi) != AF_INET6 && mp_cap->safi != BGP_MP_SAFI_UNICAST)
1253 {
1254 LOG(4, 0, 0, "Unsupported multiprotocol AFI %d and SAFI %d from BGP peer %s\n",
1255 mp_cap->afi, mp_cap->safi, peer->name);
1256
1257 bgp_send_notification_full(peer, BGP_ERR_OPEN, BGP_ERR_OPN_UNSUP_CAP,
1258 (char *)capability, 2 + capability->len);
1259 /* we don't terminate, still; we just jump to the next one */
1260 continue;
1261 }
1262
1263 peer->handle_ipv6_routes = 1;
1264 }
1265 }
1266
1267 /* next transition requires an exchange of keepalives */
1268 bgp_send_keepalive(peer);
1269 }
1270
1271 break;
1272
1273 case BGP_MSG_KEEPALIVE:
1274 if (peer->state == OpenConfirm)
1275 {
1276 peer->state = peer->next_state = Established;
1277 peer->state_time = time_now;
1278 peer->keepalive_time = time_now + peer->keepalive;
1279 peer->update_routes = 1;
1280 peer->retry_count = 0;
1281 peer->retry_time = 0;
1282
1283 LOG(4, 0, 0, "BGP peer %s: state Established\n", peer->name);
1284 }
1285
1286 break;
1287
1288 case BGP_MSG_NOTIFICATION:
1289 if (len > sizeof(p->header))
1290 {
1291 struct bgp_data_notification *notification =
1292 (struct bgp_data_notification *) p->data;
1293
1294 if (notification->error_code == BGP_ERR_CEASE)
1295 {
1296 LOG(4, 0, 0, "BGP peer %s sent CEASE\n", peer->name);
1297 bgp_restart(peer);
1298 return 0;
1299 }
1300
1301 if (notification->error_code == BGP_ERR_OPEN
1302 && notification->error_subcode == BGP_ERR_OPN_UNSUP_CAP)
1303 {
1304 /* the only capability we advertise is this one, so upon receiving
1305 an "unsupported capability" message, we disable IPv6 routes for
1306 this peer */
1307 LOG(4, 0, 0, "BGP peer %s doesn't support IPv6 routes advertisement\n", peer->name);
1308 peer->handle_ipv6_routes = 0;
1309 break;
1310 }
1311
1312 /* FIXME: should handle more notifications */
1313 LOG(4, 0, 0, "BGP peer %s sent unhandled NOTIFICATION %d\n",
1314 peer->name, (int) notification->error_code);
1315 }
1316
1317 break;
1318 }
1319
1320 /* reset timer */
1321 peer->expire_time = time_now + peer->hold;
1322
1323 /* see if there's another message in the same packet/buffer */
1324 if (peer->inbuf->done > len)
1325 {
1326 peer->inbuf->done -= len;
1327 memmove(p, (char *) p + len, peer->inbuf->done);
1328 }
1329 else
1330 {
1331 peer->inbuf->packet.header.len = 0;
1332 peer->inbuf->done = 0;
1333 }
1334
1335 return peer->inbuf->done;
1336 }
1337
1338 /* send/buffer OPEN message */
1339 static int bgp_send_open(struct bgp_peer *peer)
1340 {
1341 struct bgp_data_open data;
1342 struct bgp_mp_cap_param mp_ipv6 = { htons(AF_INET6), 0, BGP_MP_SAFI_UNICAST };
1343 struct bgp_capability cap_mp_ipv6;
1344 struct bgp_opt_param param_cap_mp_ipv6;
1345 uint16_t len = sizeof(peer->outbuf->packet.header);
1346
1347 memset(peer->outbuf->packet.header.marker, 0xff,
1348 sizeof(peer->outbuf->packet.header.marker));
1349
1350 peer->outbuf->packet.header.type = BGP_MSG_OPEN;
1351
1352 data.version = BGP_VERSION;
1353 data.as = htons(our_as);
1354 data.hold_time = htons(peer->hold);
1355 data.identifier = my_address;
1356
1357 /* construct the param and capability */
1358 cap_mp_ipv6.code = BGP_CAP_CODE_MP;
1359 cap_mp_ipv6.len = sizeof(mp_ipv6);
1360 memcpy(&cap_mp_ipv6.value, &mp_ipv6, cap_mp_ipv6.len);
1361
1362 param_cap_mp_ipv6.type = BGP_PARAM_TYPE_CAPABILITY;
1363 param_cap_mp_ipv6.len = 2 + sizeof(mp_ipv6);
1364 memcpy(&param_cap_mp_ipv6.value, &cap_mp_ipv6, param_cap_mp_ipv6.len);
1365
1366 data.opt_len = 2 + param_cap_mp_ipv6.len;
1367 memcpy(&data.opt_params, &param_cap_mp_ipv6, data.opt_len);
1368
1369 memcpy(peer->outbuf->packet.data, &data, BGP_DATA_OPEN_SIZE);
1370 len += BGP_DATA_OPEN_SIZE;
1371
1372 peer->outbuf->packet.header.len = htons(len);
1373 peer->outbuf->done = 0;
1374 peer->next_state = OpenSent;
1375
1376 return bgp_write(peer);
1377 }
1378
1379 /* send/buffer KEEPALIVE message */
1380 static int bgp_send_keepalive(struct bgp_peer *peer)
1381 {
1382 memset(peer->outbuf->packet.header.marker, 0xff,
1383 sizeof(peer->outbuf->packet.header.marker));
1384
1385 peer->outbuf->packet.header.type = BGP_MSG_KEEPALIVE;
1386 peer->outbuf->packet.header.len =
1387 htons(sizeof(peer->outbuf->packet.header));
1388
1389 peer->outbuf->done = 0;
1390 peer->next_state = (peer->state == OpenSent) ? OpenConfirm : peer->state;
1391
1392 return bgp_write(peer);
1393 }
1394
1395 /* send/buffer UPDATE message */
1396 static int bgp_send_update(struct bgp_peer *peer)
1397 {
1398 uint16_t unf_len = 0;
1399 uint16_t attr_len;
1400 uint16_t len = sizeof(peer->outbuf->packet.header);
1401 struct bgp_route_list *have = peer->routes;
1402 struct bgp_route_list *want = peer->routing ? bgp_routes : 0;
1403 struct bgp_route_list *e = 0;
1404 struct bgp_route_list *add = 0;
1405 int s;
1406
1407 char *data = (char *) &peer->outbuf->packet.data;
1408
1409 /* need leave room for attr_len, bgp_path_attrs and one prefix */
1410 char *max = (char *) &peer->outbuf->packet.data
1411 + sizeof(peer->outbuf->packet.data)
1412 - sizeof(attr_len) - peer->path_attr_len - sizeof(struct bgp_ip_prefix);
1413
1414 /* skip over unf_len */
1415 data += sizeof(unf_len);
1416 len += sizeof(unf_len);
1417
1418 memset(peer->outbuf->packet.header.marker, 0xff,
1419 sizeof(peer->outbuf->packet.header.marker));
1420
1421 peer->outbuf->packet.header.type = BGP_MSG_UPDATE;
1422
1423 peer->update_routes = 0; /* tentatively clear */
1424
1425 /* find differences */
1426 while ((have || want) && data < (max - sizeof(struct bgp_ip_prefix)))
1427 {
1428 if (have)
1429 s = want
1430 ? memcmp(&have->dest, &want->dest, sizeof(have->dest))
1431 : -1;
1432 else
1433 s = 1;
1434
1435 if (s < 0) /* found one to delete */
1436 {
1437 struct bgp_route_list *tmp = have;
1438 have = have->next;
1439
1440 s = BGP_IP_PREFIX_SIZE(tmp->dest);
1441 memcpy(data, &tmp->dest, s);
1442 data += s;
1443 unf_len += s;
1444 len += s;
1445
1446 LOG(5, 0, 0, "Withdrawing route %s/%d from BGP peer %s\n",
1447 fmtaddr(tmp->dest.prefix, 0), tmp->dest.len, peer->name);
1448
1449 free(tmp);
1450
1451 if (e)
1452 e->next = have;
1453 else
1454 peer->routes = have;
1455 }
1456 else
1457 {
1458 if (!s) /* same */
1459 {
1460 e = have; /* stash the last found to relink above */
1461 have = have->next;
1462 want = want->next;
1463 }
1464 else if (s > 0) /* addition reqd. */
1465 {
1466 if (add)
1467 {
1468 peer->update_routes = 1; /* only one add per packet */
1469 if (!have)
1470 break;
1471 }
1472 else
1473 add = want;
1474
1475 if (want)
1476 want = want->next;
1477 }
1478 }
1479 }
1480
1481 if (have || want)
1482 peer->update_routes = 1; /* more to do */
1483
1484 /* anything changed? */
1485 if (!(unf_len || add))
1486 return 1;
1487
1488 /* go back and insert unf_len */
1489 unf_len = htons(unf_len);
1490 memcpy(&peer->outbuf->packet.data, &unf_len, sizeof(unf_len));
1491
1492 if (add)
1493 {
1494 if (!(e = malloc(sizeof(*e))))
1495 {
1496 LOG(0, 0, 0, "Can't allocate route for %s/%d (%s)\n",
1497 fmtaddr(add->dest.prefix, 0), add->dest.len, strerror(errno));
1498
1499 return 0;
1500 }
1501
1502 memcpy(e, add, sizeof(*e));
1503 e->next = 0;
1504 peer->routes = bgp_insert_route(peer->routes, e);
1505
1506 attr_len = htons(peer->path_attr_len);
1507 memcpy(data, &attr_len, sizeof(attr_len));
1508 data += sizeof(attr_len);
1509 len += sizeof(attr_len);
1510
1511 memcpy(data, peer->path_attrs, peer->path_attr_len);
1512 data += peer->path_attr_len;
1513 len += peer->path_attr_len;
1514
1515 s = BGP_IP_PREFIX_SIZE(add->dest);
1516 memcpy(data, &add->dest, s);
1517 data += s;
1518 len += s;
1519
1520 LOG(5, 0, 0, "Advertising route %s/%d to BGP peer %s\n",
1521 fmtaddr(add->dest.prefix, 0), add->dest.len, peer->name);
1522 }
1523 else
1524 {
1525 attr_len = 0;
1526 memcpy(data, &attr_len, sizeof(attr_len));
1527 data += sizeof(attr_len);
1528 len += sizeof(attr_len);
1529 }
1530
1531 peer->outbuf->packet.header.len = htons(len);
1532 peer->outbuf->done = 0;
1533
1534 return bgp_write(peer);
1535 }
1536
1537 /* send/buffer UPDATE message for IPv6 routes */
1538 static int bgp_send_update6(struct bgp_peer *peer)
1539 {
1540 uint16_t unf_len = 0;
1541 uint16_t attr_len;
1542 char *unreach_len;
1543 uint8_t reach_len;
1544 uint16_t len = sizeof(peer->outbuf->packet.header);
1545 struct bgp_route6_list *have = peer->routes6;
1546 struct bgp_route6_list *want = peer->routing ? bgp_routes6 : 0;
1547 struct bgp_route6_list *e = 0;
1548 struct bgp_route6_list *add = 0;
1549 int s;
1550 char ipv6addr[INET6_ADDRSTRLEN];
1551
1552 char *data = (char *) &peer->outbuf->packet.data;
1553
1554 /* need leave room for attr_len, bgp_path_attrs and one prefix */
1555 char *max = (char *) &peer->outbuf->packet.data
1556 + sizeof(peer->outbuf->packet.data)
1557 - sizeof(attr_len) - peer->path_attr_len_without_nexthop
1558 - BGP_PATH_ATTR_MP_REACH_NLRI_PARTIAL_SIZE - sizeof(struct bgp_ip6_prefix);
1559
1560 memset(peer->outbuf->packet.header.marker, 0xff,
1561 sizeof(peer->outbuf->packet.header.marker));
1562
1563 peer->outbuf->packet.header.type = BGP_MSG_UPDATE;
1564
1565 /* insert non-MP unf_len */
1566 memcpy(data, &unf_len, sizeof(unf_len));
1567 /* skip over attr_len too; will be filled when known */
1568 data += sizeof(unf_len) + sizeof(attr_len);
1569 len += sizeof(unf_len) + sizeof(attr_len);
1570
1571 /* copy usual attributes */
1572 memcpy(data, peer->path_attrs, peer->path_attr_len_without_nexthop);
1573 data += peer->path_attr_len_without_nexthop;
1574 len += peer->path_attr_len_without_nexthop;
1575
1576 /* copy MP unreachable NLRI heading */
1577 memcpy(data, peer->mp_unreach_nlri_partial,
1578 BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE);
1579 /* remember where to update this attr len */
1580 unreach_len = data + 2;
1581 data += BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE;
1582 len += BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE;
1583
1584 peer->update_routes6 = 0; /* tentatively clear */
1585
1586 /* find differences */
1587 while ((have || want) && data < (max - sizeof(struct bgp_ip6_prefix)))
1588 {
1589 if (have)
1590 s = want
1591 ? memcmp(&have->dest, &want->dest, sizeof(have->dest))
1592 : -1;
1593 else
1594 s = 1;
1595
1596 if (s < 0) /* found one to delete */
1597 {
1598 struct bgp_route6_list *tmp = have;
1599 have = have->next;
1600
1601 s = BGP_IP_PREFIX_SIZE(tmp->dest);
1602 memcpy(data, &tmp->dest, s);
1603 data += s;
1604 unf_len += s;
1605 len += s;
1606
1607 LOG(5, 0, 0, "Withdrawing route %s/%d from BGP peer %s\n",
1608 inet_ntop(AF_INET6, &tmp->dest.prefix, ipv6addr, INET6_ADDRSTRLEN),
1609 tmp->dest.len, peer->name);
1610
1611 free(tmp);
1612
1613 if (e)
1614 e->next = have;
1615 else
1616 peer->routes6 = have;
1617 }
1618 else
1619 {
1620 if (!s) /* same */
1621 {
1622 e = have; /* stash the last found to relink above */
1623 have = have->next;
1624 want = want->next;
1625 }
1626 else if (s > 0) /* addition reqd. */
1627 {
1628 if (add)
1629 {
1630 peer->update_routes6 = 1; /* only one add per packet */
1631 if (!have)
1632 break;
1633 }
1634 else
1635 add = want;
1636
1637 if (want)
1638 want = want->next;
1639 }
1640 }
1641 }
1642
1643 if (have || want)
1644 peer->update_routes6 = 1; /* more to do */
1645
1646 /* anything changed? */
1647 if (!(unf_len || add))
1648 return 1;
1649
1650 /* go back and insert MP unf_len */
1651 unf_len += sizeof(struct bgp_attr_mp_unreach_nlri_partial);
1652 unf_len = htons(unf_len);
1653 memcpy(&unreach_len, &unf_len, sizeof(unf_len));
1654
1655 if (add)
1656 {
1657 if (!(e = malloc(sizeof(*e))))
1658 {
1659 LOG(0, 0, 0, "Can't allocate route for %s/%d (%s)\n",
1660 inet_ntop(AF_INET6, &add->dest.prefix, ipv6addr, INET6_ADDRSTRLEN),
1661 add->dest.len, strerror(errno));
1662
1663 return 0;
1664 }
1665
1666 memcpy(e, add, sizeof(*e));
1667 e->next = 0;
1668 peer->routes6 = bgp_insert_route6(peer->routes6, e);
1669
1670 /* copy MP reachable NLRI heading */
1671 memcpy(data, peer->mp_reach_nlri_partial,
1672 BGP_PATH_ATTR_MP_REACH_NLRI_PARTIAL_SIZE);
1673 /* with proper len */
1674 reach_len = BGP_IP_PREFIX_SIZE(add->dest);
1675 data[2] = reach_len;
1676 data += BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE;
1677 len += BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE;
1678
1679 memcpy(data, &add->dest, reach_len);
1680 data += reach_len;
1681 len += reach_len;
1682
1683 LOG(5, 0, 0, "Advertising route %s/%d to BGP peer %s\n",
1684 inet_ntop(AF_INET6, &add->dest.prefix, ipv6addr, INET6_ADDRSTRLEN),
1685 add->dest.len, peer->name);
1686 }
1687
1688 /* go back and insert attr_len */
1689 attr_len = htons(len - 4);
1690 memcpy(&peer->outbuf->packet.data + 2, &attr_len, sizeof(attr_len));
1691
1692 peer->outbuf->packet.header.len = htons(len);
1693 peer->outbuf->done = 0;
1694
1695 return bgp_write(peer);
1696 }
1697
1698 /* send/buffer NOTIFICATION message */
1699 static int bgp_send_notification(struct bgp_peer *peer, uint8_t code,
1700 uint8_t subcode)
1701 {
1702 return bgp_send_notification_full(peer, code, subcode, NULL, 0);
1703 }
1704
1705 static int bgp_send_notification_full(struct bgp_peer *peer, uint8_t code,
1706 uint8_t subcode, char *notification_data, uint16_t data_len)
1707 {
1708 struct bgp_data_notification data;
1709 uint16_t len = 0;
1710
1711 data.error_code = code;
1712 len += sizeof(data.error_code);
1713
1714 data.error_subcode = subcode;
1715 len += sizeof(data.error_code);
1716
1717 memcpy(data.data, notification_data, data_len);
1718 len += data_len;
1719
1720 memset(peer->outbuf->packet.header.marker, 0xff,
1721 sizeof(peer->outbuf->packet.header.marker));
1722
1723 peer->outbuf->packet.header.type = BGP_MSG_NOTIFICATION;
1724 peer->outbuf->packet.header.len =
1725 htons(sizeof(peer->outbuf->packet.header) + len);
1726
1727 memcpy(peer->outbuf->packet.data, &data, len);
1728
1729 peer->outbuf->done = 0;
1730 peer->next_state = code == BGP_ERR_CEASE ? Disabled : Idle;
1731
1732 /* we're dying; ignore any pending input */
1733 peer->inbuf->packet.header.len = 0;
1734 peer->inbuf->done = 0;
1735
1736 return bgp_write(peer);
1737 }