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