420a925f6af74f88cbab04ac436229467e5bfd65
[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
53 static uint16_t our_as;
54 static struct bgp_route_list *bgp_routes = 0;
55 static struct bgp_route6_list *bgp_routes6 = 0;
56
57 int bgp_configured = 0;
58 struct bgp_peer *bgp_peers = 0;
59
60 /* prepare peer structure, globals */
61 int bgp_setup(int as)
62 {
63 int i;
64 struct bgp_peer *peer;
65
66 for (i = 0; i < BGP_NUM_PEERS; i++)
67 {
68 peer = &bgp_peers[i];
69 memset(peer, 0, sizeof(*peer));
70
71 peer->addr = INADDR_NONE;
72 peer->sock = -1;
73 peer->state = peer->next_state = Disabled;
74
75 if (!((peer->outbuf = malloc(sizeof(*peer->outbuf)))
76 && (peer->inbuf = malloc(sizeof(*peer->inbuf)))))
77 {
78 LOG(0, 0, 0, "Can't allocate buffers for bgp peer (%s)\n",
79 strerror(errno));
80
81 return 0;
82 }
83
84 peer->edata.type = FD_TYPE_BGP;
85 peer->edata.index = i;
86 peer->events = 0;
87 }
88
89 if (as < 1)
90 as = 0;
91
92 if ((our_as = as))
93 return 0;
94
95 bgp_routes = 0;
96 bgp_routes6 = 0;
97 bgp_configured = 0; /* set by bgp_start */
98
99 return 1;
100 }
101
102 /* start connection with a peer */
103 int bgp_start(struct bgp_peer *peer, char *name, int as, int keepalive,
104 int hold, int enable)
105 {
106 struct hostent *h;
107 int ibgp;
108 int i;
109 struct bgp_path_attr a;
110 char path_attrs[64];
111 char *p = path_attrs;
112 in_addr_t ip;
113 uint32_t metric = htonl(BGP_METRIC);
114 uint32_t no_export = htonl(BGP_COMMUNITY_NO_EXPORT);
115
116 if (!our_as)
117 return 0;
118
119 if (peer->state != Disabled)
120 bgp_halt(peer);
121
122 snprintf(peer->name, sizeof(peer->name), "%s", name);
123
124 if (!(h = gethostbyname(name)) || h->h_addrtype != AF_INET)
125 {
126 LOG(0, 0, 0, "Can't get address for BGP peer %s (%s)\n",
127 name, h ? "no address" : hstrerror(h_errno));
128
129 return 0;
130 }
131
132 memcpy(&peer->addr, h->h_addr, sizeof(peer->addr));
133 peer->as = as > 0 ? as : our_as;
134 ibgp = peer->as == our_as;
135
136 /* set initial timer values */
137 peer->init_keepalive = keepalive == -1 ? BGP_KEEPALIVE_TIME : keepalive;
138 peer->init_hold = hold == -1 ? BGP_HOLD_TIME : hold;
139
140 if (peer->init_hold < 3)
141 peer->init_hold = 3;
142
143 if (peer->init_keepalive * 3 > peer->init_hold)
144 peer->init_keepalive = peer->init_hold / 3;
145
146 /* clear buffers, go to Idle state */
147 peer->next_state = Idle;
148 bgp_clear(peer);
149
150 /* set initial routing state */
151 peer->routing = enable;
152
153 /* all our routes use the same attributes, so prepare it in advance */
154 if (peer->path_attrs)
155 free(peer->path_attrs);
156
157 peer->path_attr_len = 0;
158
159 /* ORIGIN */
160 a.flags = BGP_PATH_ATTR_FLAG_TRANS;
161 a.code = BGP_PATH_ATTR_CODE_ORIGIN;
162 a.data.s.len = 1;
163 a.data.s.value[0] = BGP_PATH_ATTR_CODE_ORIGIN_IGP;
164
165 #define ADD_ATTRIBUTE() do { \
166 i = BGP_PATH_ATTR_SIZE(a); \
167 memcpy(p, &a, i); \
168 p += i; \
169 peer->path_attr_len += i; } while (0)
170
171 ADD_ATTRIBUTE();
172
173 /* AS_PATH */
174 a.flags = BGP_PATH_ATTR_FLAG_TRANS;
175 a.code = BGP_PATH_ATTR_CODE_AS_PATH;
176 if (ibgp)
177 {
178 /* empty path */
179 a.data.s.len = 0;
180 }
181 else
182 {
183 /* just our AS */
184 struct {
185 uint8_t type;
186 uint8_t len;
187 uint16_t value;
188 } as_path = {
189 BGP_PATH_ATTR_CODE_AS_PATH_AS_SEQUENCE,
190 1,
191 htons(our_as),
192 };
193
194 a.data.s.len = sizeof(as_path);
195 memcpy(&a.data.s.value, &as_path, sizeof(as_path));
196 }
197
198 ADD_ATTRIBUTE();
199
200 /* MULTI_EXIT_DISC */
201 a.flags = BGP_PATH_ATTR_FLAG_OPTIONAL;
202 a.code = BGP_PATH_ATTR_CODE_MULTI_EXIT_DISC;
203 a.data.s.len = sizeof(metric);
204 memcpy(a.data.s.value, &metric, sizeof(metric));
205
206 ADD_ATTRIBUTE();
207
208 if (ibgp)
209 {
210 uint32_t local_pref = htonl(BGP_LOCAL_PREF);
211
212 /* LOCAL_PREF */
213 a.flags = BGP_PATH_ATTR_FLAG_TRANS;
214 a.code = BGP_PATH_ATTR_CODE_LOCAL_PREF;
215 a.data.s.len = sizeof(local_pref);
216 memcpy(a.data.s.value, &local_pref, sizeof(local_pref));
217
218 ADD_ATTRIBUTE();
219 }
220
221 /* COMMUNITIES */
222 a.flags = BGP_PATH_ATTR_FLAG_OPTIONAL | BGP_PATH_ATTR_FLAG_TRANS;
223 a.code = BGP_PATH_ATTR_CODE_COMMUNITIES;
224 a.data.s.len = sizeof(no_export);
225 memcpy(a.data.s.value, &no_export, sizeof(no_export));
226
227 ADD_ATTRIBUTE();
228
229 /* remember the len before adding NEXT_HOP */
230 peer->path_attr_len_without_nexthop = peer->path_attr_len;
231
232 /* NEXT_HOP */
233 a.flags = BGP_PATH_ATTR_FLAG_TRANS;
234 a.code = BGP_PATH_ATTR_CODE_NEXT_HOP;
235 ip = my_address; /* we're it */
236 a.data.s.len = sizeof(ip);
237 memcpy(a.data.s.value, &ip, sizeof(ip));
238
239 ADD_ATTRIBUTE();
240
241 if (!(peer->path_attrs = malloc(peer->path_attr_len)))
242 {
243 LOG(0, 0, 0, "Can't allocate path_attrs for %s (%s)\n",
244 name, strerror(errno));
245
246 return 0;
247 }
248
249 memcpy(peer->path_attrs, path_attrs, peer->path_attr_len);
250
251 /* multiprotocol attributes initialization */
252 if (config->ipv6_prefix.s6_addr[0])
253 {
254 struct bgp_attr_mp_reach_nlri_partial mp_reach_nlri_partial;
255 struct bgp_attr_mp_unreach_nlri_partial mp_unreach_nlri_partial;
256
257 a.flags = BGP_PATH_ATTR_FLAG_OPTIONAL;
258 a.code = BGP_PATH_ATTR_CODE_MP_REACH_NLRI;
259 a.data.s.len = 0; /* will be set on UPDATE */
260
261 mp_reach_nlri_partial.afi = htons(BGP_MP_AFI_IPv6);
262 mp_reach_nlri_partial.safi = BGP_MP_SAFI_UNICAST;
263 mp_reach_nlri_partial.reserved = 0;
264 mp_reach_nlri_partial.next_hop_len = 16;
265
266 /* use the defined nexthop6, or our address in ipv6_prefix */
267 if (config->nexthop6_address.s6_addr[0])
268 memcpy(&mp_reach_nlri_partial.next_hop,
269 &config->nexthop6_address.s6_addr, 16);
270 else
271 {
272 /* our address is ipv6prefix::1 */
273 memcpy(&mp_reach_nlri_partial.next_hop,
274 &config->ipv6_prefix.s6_addr, 16);
275 mp_reach_nlri_partial.next_hop[15] = 1;
276 }
277
278 memcpy(&a.data.s.value, &mp_reach_nlri_partial,
279 sizeof(struct bgp_attr_mp_reach_nlri_partial));
280 memcpy(&peer->mp_reach_nlri_partial, &a,
281 BGP_PATH_ATTR_MP_REACH_NLRI_PARTIAL_SIZE);
282
283 a.flags = BGP_PATH_ATTR_FLAG_OPTIONAL | BGP_PATH_ATTR_FLAG_EXTLEN;
284 a.code = BGP_PATH_ATTR_CODE_MP_UNREACH_NLRI;
285 a.data.e.len = 0; /* will be set on UPDATE */
286
287 mp_unreach_nlri_partial.afi = htons(BGP_MP_AFI_IPv6);
288 mp_unreach_nlri_partial.safi = BGP_MP_SAFI_UNICAST;
289
290 memcpy(&a.data.e.value, &mp_unreach_nlri_partial,
291 sizeof(struct bgp_attr_mp_unreach_nlri_partial));
292 memcpy(&peer->mp_unreach_nlri_partial, &a,
293 BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE);
294 }
295
296 peer->mp_handling = HandlingUnknown;
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].mp_handling == HandleIPv6Routes)
559 bgp_peers[i].update_routes6 = 1;
560
561 LOG(4, 0, 0, "Registered BGP route %s/%d\n",
562 inet_ntop(AF_INET6, &ip, ipv6addr, INET6_ADDRSTRLEN), add.dest.len);
563
564 return 1;
565 }
566
567 /* remove route from list for peers */
568 int bgp_del_route(in_addr_t ip, in_addr_t mask)
569 {
570 struct bgp_route_list *r = bgp_routes;
571 struct bgp_route_list *e = 0;
572 struct bgp_route_list del;
573 int i;
574
575 bgp_cidr(ip, mask, &del.dest);
576 del.next = 0;
577
578 /* find entry in routes list and remove */
579 while (r)
580 {
581 i = memcmp(&r->dest, &del.dest, sizeof(r->dest));
582 if (!i)
583 {
584 if (e)
585 e->next = r->next;
586 else
587 bgp_routes = r->next;
588
589 free(r);
590 break;
591 }
592
593 e = r;
594
595 if (i > 0)
596 r = 0; /* stop */
597 else
598 r = r->next;
599 }
600
601 /* not found */
602 if (!r)
603 return 1;
604
605 /* flag established peers for update */
606 for (i = 0; i < BGP_NUM_PEERS; i++)
607 if (bgp_peers[i].state == Established)
608 bgp_peers[i].update_routes = 1;
609
610 LOG(4, 0, 0, "Removed BGP route %s/%d\n",
611 fmtaddr(del.dest.prefix, 0), del.dest.len);
612
613 return 1;
614 }
615
616 /* remove route from list for peers */
617 int bgp_del_route6(struct in6_addr ip, int prefixlen)
618 {
619 struct bgp_route6_list *r = bgp_routes6;
620 struct bgp_route6_list *e = 0;
621 struct bgp_route6_list del;
622 int i;
623 char ipv6addr[INET6_ADDRSTRLEN];
624
625 memcpy(&del.dest.prefix, &ip.s6_addr, 16);
626 del.dest.len = prefixlen;
627 del.next = 0;
628
629 /* find entry in routes list and remove */
630 while (r)
631 {
632 i = memcmp(&r->dest, &del.dest, sizeof(r->dest));
633 if (!i)
634 {
635 if (e)
636 e->next = r->next;
637 else
638 bgp_routes6 = r->next;
639
640 free(r);
641 break;
642 }
643
644 e = r;
645
646 if (i > 0)
647 r = 0; /* stop */
648 else
649 r = r->next;
650 }
651
652 /* not found */
653 if (!r)
654 return 1;
655
656 /* flag established peers for update */
657 for (i = 0; i < BGP_NUM_PEERS; i++)
658 if (bgp_peers[i].state == Established
659 && bgp_peers[i].mp_handling == HandleIPv6Routes)
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 *)((char *)&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 /* look for BGP multiprotocol capability */
1215 for (capability_offset = 0;
1216 capability_offset < capabilities_len;
1217 capability_offset += 2 + capability->len)
1218 {
1219 capability = (struct bgp_capability *)(capabilities + capability_offset);
1220
1221 /* sensible check */
1222 if (capabilities_len - capability_offset < 2
1223 || capability->len > capabilities_len - capability_offset - 2)
1224 {
1225 LOG(1, 0, 0, "Malformed Capabilities list from BGP peer %s\n",
1226 peer->name);
1227
1228 bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_UNSPEC);
1229 return 0;
1230 }
1231
1232 /* we only know one capability code */
1233 if (capability->code != BGP_CAP_CODE_MP
1234 && capability->len != sizeof(struct bgp_mp_cap_param))
1235 {
1236 LOG(4, 0, 0, "Unsupported Capability code %d from BGP peer %s\n",
1237 capability->code, peer->name);
1238
1239 /* we don't terminate, still; we just jump to the next one */
1240 continue;
1241 }
1242
1243 mp_cap = (struct bgp_mp_cap_param *)&capability->value;
1244 /* the only <AFI, SAFI> tuple we support */
1245 if (ntohs(mp_cap->afi) != BGP_MP_AFI_IPv6 && mp_cap->safi != BGP_MP_SAFI_UNICAST)
1246 {
1247 LOG(4, 0, 0, "Unsupported multiprotocol AFI %d and SAFI %d from BGP peer %s\n",
1248 mp_cap->afi, mp_cap->safi, peer->name);
1249
1250 /* we don't terminate, still; we just jump to the next one */
1251 continue;
1252 }
1253
1254 /* yes it can! */
1255 peer->mp_handling = HandleIPv6Routes;
1256 }
1257 }
1258
1259 if (peer->mp_handling != HandleIPv6Routes)
1260 {
1261 peer->mp_handling = DoesntHandleIPv6Routes;
1262 if (config->ipv6_prefix.s6_addr[0])
1263 LOG(1, 0, 0, "Warning: BGP peer %s doesn't handle IPv6 prefixes updates\n",
1264 peer->name);
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_PARAM)
1303 {
1304 LOG(4, 0, 0, "BGP peer %s doesn't support BGP Capabilities\n", peer->name);
1305 peer->mp_handling = DoesntHandleIPv6Routes;
1306 bgp_restart(peer);
1307 return 0;
1308 }
1309
1310 if (notification->error_code == BGP_ERR_OPEN
1311 && notification->error_subcode == BGP_ERR_OPN_UNSUP_CAP)
1312 {
1313 /* the only capability we advertise is this one, so upon receiving
1314 an "unsupported capability" message, we disable IPv6 routes for
1315 this peer */
1316 LOG(4, 0, 0, "BGP peer %s doesn't support IPv6 routes advertisement\n", peer->name);
1317 peer->mp_handling = DoesntHandleIPv6Routes;
1318 break;
1319 }
1320
1321 /* FIXME: should handle more notifications */
1322 LOG(4, 0, 0, "BGP peer %s sent unhandled NOTIFICATION %d\n",
1323 peer->name, (int) notification->error_code);
1324 }
1325
1326 break;
1327 }
1328
1329 /* reset timer */
1330 peer->expire_time = time_now + peer->hold;
1331
1332 /* see if there's another message in the same packet/buffer */
1333 if (peer->inbuf->done > len)
1334 {
1335 peer->inbuf->done -= len;
1336 memmove(p, (char *) p + len, peer->inbuf->done);
1337 }
1338 else
1339 {
1340 peer->inbuf->packet.header.len = 0;
1341 peer->inbuf->done = 0;
1342 }
1343
1344 return peer->inbuf->done;
1345 }
1346
1347 /* send/buffer OPEN message */
1348 static int bgp_send_open(struct bgp_peer *peer)
1349 {
1350 struct bgp_data_open data;
1351 struct bgp_mp_cap_param mp_ipv6 = { htons(BGP_MP_AFI_IPv6), 0, BGP_MP_SAFI_UNICAST };
1352 struct bgp_capability cap_mp_ipv6;
1353 struct bgp_opt_param param_cap_mp_ipv6;
1354 uint16_t len = sizeof(peer->outbuf->packet.header);
1355
1356 memset(peer->outbuf->packet.header.marker, 0xff,
1357 sizeof(peer->outbuf->packet.header.marker));
1358
1359 peer->outbuf->packet.header.type = BGP_MSG_OPEN;
1360
1361 data.version = BGP_VERSION;
1362 data.as = htons(our_as);
1363 data.hold_time = htons(peer->hold);
1364 data.identifier = my_address;
1365
1366 /* if we know peer doesn't support MP (mp_handling == DoesntHandleIPv6Routes)
1367 then don't add this parameter */
1368 if (config->ipv6_prefix.s6_addr[0]
1369 && (peer->mp_handling == HandlingUnknown
1370 || peer->mp_handling == HandleIPv6Routes))
1371 {
1372 /* construct the param and capability */
1373 cap_mp_ipv6.code = BGP_CAP_CODE_MP;
1374 cap_mp_ipv6.len = sizeof(mp_ipv6);
1375 memcpy(&cap_mp_ipv6.value, &mp_ipv6, cap_mp_ipv6.len);
1376
1377 param_cap_mp_ipv6.type = BGP_PARAM_TYPE_CAPABILITY;
1378 param_cap_mp_ipv6.len = 2 + sizeof(mp_ipv6);
1379 memcpy(&param_cap_mp_ipv6.value, &cap_mp_ipv6, param_cap_mp_ipv6.len);
1380
1381 data.opt_len = 2 + param_cap_mp_ipv6.len;
1382 memcpy(&data.opt_params, &param_cap_mp_ipv6, data.opt_len);
1383 }
1384 else
1385 data.opt_len = 0;
1386
1387 memcpy(peer->outbuf->packet.data, &data, BGP_DATA_OPEN_SIZE + data.opt_len);
1388 len += BGP_DATA_OPEN_SIZE + data.opt_len;
1389
1390 peer->outbuf->packet.header.len = htons(len);
1391 peer->outbuf->done = 0;
1392 peer->next_state = OpenSent;
1393
1394 return bgp_write(peer);
1395 }
1396
1397 /* send/buffer KEEPALIVE message */
1398 static int bgp_send_keepalive(struct bgp_peer *peer)
1399 {
1400 memset(peer->outbuf->packet.header.marker, 0xff,
1401 sizeof(peer->outbuf->packet.header.marker));
1402
1403 peer->outbuf->packet.header.type = BGP_MSG_KEEPALIVE;
1404 peer->outbuf->packet.header.len =
1405 htons(sizeof(peer->outbuf->packet.header));
1406
1407 peer->outbuf->done = 0;
1408 peer->next_state = (peer->state == OpenSent) ? OpenConfirm : peer->state;
1409
1410 return bgp_write(peer);
1411 }
1412
1413 /* send/buffer UPDATE message */
1414 static int bgp_send_update(struct bgp_peer *peer)
1415 {
1416 uint16_t unf_len = 0;
1417 uint16_t attr_len;
1418 uint16_t len = sizeof(peer->outbuf->packet.header);
1419 struct bgp_route_list *have = peer->routes;
1420 struct bgp_route_list *want = peer->routing ? bgp_routes : 0;
1421 struct bgp_route_list *e = 0;
1422 struct bgp_route_list *add = 0;
1423 int s;
1424
1425 char *data = (char *) &peer->outbuf->packet.data;
1426
1427 /* need leave room for attr_len, bgp_path_attrs and one prefix */
1428 char *max = (char *) &peer->outbuf->packet.data
1429 + sizeof(peer->outbuf->packet.data)
1430 - sizeof(attr_len) - peer->path_attr_len - sizeof(struct bgp_ip_prefix);
1431
1432 /* skip over unf_len */
1433 data += sizeof(unf_len);
1434 len += sizeof(unf_len);
1435
1436 memset(peer->outbuf->packet.header.marker, 0xff,
1437 sizeof(peer->outbuf->packet.header.marker));
1438
1439 peer->outbuf->packet.header.type = BGP_MSG_UPDATE;
1440
1441 peer->update_routes = 0; /* tentatively clear */
1442
1443 /* find differences */
1444 while ((have || want) && data < (max - sizeof(struct bgp_ip_prefix)))
1445 {
1446 if (have)
1447 s = want
1448 ? memcmp(&have->dest, &want->dest, sizeof(have->dest))
1449 : -1;
1450 else
1451 s = 1;
1452
1453 if (s < 0) /* found one to delete */
1454 {
1455 struct bgp_route_list *tmp = have;
1456 have = have->next;
1457
1458 s = BGP_IP_PREFIX_SIZE(tmp->dest);
1459 memcpy(data, &tmp->dest, s);
1460 data += s;
1461 unf_len += s;
1462 len += s;
1463
1464 LOG(5, 0, 0, "Withdrawing route %s/%d from BGP peer %s\n",
1465 fmtaddr(tmp->dest.prefix, 0), tmp->dest.len, peer->name);
1466
1467 free(tmp);
1468
1469 if (e)
1470 e->next = have;
1471 else
1472 peer->routes = have;
1473 }
1474 else
1475 {
1476 if (!s) /* same */
1477 {
1478 e = have; /* stash the last found to relink above */
1479 have = have->next;
1480 want = want->next;
1481 }
1482 else if (s > 0) /* addition reqd. */
1483 {
1484 if (add)
1485 {
1486 peer->update_routes = 1; /* only one add per packet */
1487 if (!have)
1488 break;
1489 }
1490 else
1491 add = want;
1492
1493 if (want)
1494 want = want->next;
1495 }
1496 }
1497 }
1498
1499 if (have || want)
1500 peer->update_routes = 1; /* more to do */
1501
1502 /* anything changed? */
1503 if (!(unf_len || add))
1504 return 1;
1505
1506 /* go back and insert unf_len */
1507 unf_len = htons(unf_len);
1508 memcpy(&peer->outbuf->packet.data, &unf_len, sizeof(unf_len));
1509
1510 if (add)
1511 {
1512 if (!(e = malloc(sizeof(*e))))
1513 {
1514 LOG(0, 0, 0, "Can't allocate route for %s/%d (%s)\n",
1515 fmtaddr(add->dest.prefix, 0), add->dest.len, strerror(errno));
1516
1517 return 0;
1518 }
1519
1520 memcpy(e, add, sizeof(*e));
1521 e->next = 0;
1522 peer->routes = bgp_insert_route(peer->routes, e);
1523
1524 attr_len = htons(peer->path_attr_len);
1525 memcpy(data, &attr_len, sizeof(attr_len));
1526 data += sizeof(attr_len);
1527 len += sizeof(attr_len);
1528
1529 memcpy(data, peer->path_attrs, peer->path_attr_len);
1530 data += peer->path_attr_len;
1531 len += peer->path_attr_len;
1532
1533 s = BGP_IP_PREFIX_SIZE(add->dest);
1534 memcpy(data, &add->dest, s);
1535 data += s;
1536 len += s;
1537
1538 LOG(5, 0, 0, "Advertising route %s/%d to BGP peer %s\n",
1539 fmtaddr(add->dest.prefix, 0), add->dest.len, peer->name);
1540 }
1541 else
1542 {
1543 attr_len = 0;
1544 memcpy(data, &attr_len, sizeof(attr_len));
1545 data += sizeof(attr_len);
1546 len += sizeof(attr_len);
1547 }
1548
1549 peer->outbuf->packet.header.len = htons(len);
1550 peer->outbuf->done = 0;
1551
1552 return bgp_write(peer);
1553 }
1554
1555 /* send/buffer UPDATE message for IPv6 routes */
1556 static int bgp_send_update6(struct bgp_peer *peer)
1557 {
1558 uint16_t unf_len = 0;
1559 uint16_t attr_len;
1560 char *unreach_len;
1561 uint8_t reach_len;
1562 uint16_t len = sizeof(peer->outbuf->packet.header);
1563 struct bgp_route6_list *have = peer->routes6;
1564 struct bgp_route6_list *want = peer->routing ? bgp_routes6 : 0;
1565 struct bgp_route6_list *e = 0;
1566 struct bgp_route6_list *add = 0;
1567 int s;
1568 char ipv6addr[INET6_ADDRSTRLEN];
1569
1570 char *data = (char *) &peer->outbuf->packet.data;
1571
1572 /* need leave room for attr_len, bgp_path_attrs and one prefix */
1573 char *max = (char *) &peer->outbuf->packet.data
1574 + sizeof(peer->outbuf->packet.data)
1575 - sizeof(attr_len) - peer->path_attr_len_without_nexthop
1576 - BGP_PATH_ATTR_MP_REACH_NLRI_PARTIAL_SIZE - sizeof(struct bgp_ip6_prefix);
1577
1578 memset(peer->outbuf->packet.header.marker, 0xff,
1579 sizeof(peer->outbuf->packet.header.marker));
1580
1581 peer->outbuf->packet.header.type = BGP_MSG_UPDATE;
1582
1583 /* insert non-MP unf_len */
1584 memcpy(data, &unf_len, sizeof(unf_len));
1585 /* skip over attr_len too; will be filled when known */
1586 data += sizeof(unf_len) + sizeof(attr_len);
1587 len += sizeof(unf_len) + sizeof(attr_len);
1588
1589 /* copy usual attributes */
1590 memcpy(data, peer->path_attrs, peer->path_attr_len_without_nexthop);
1591 data += peer->path_attr_len_without_nexthop;
1592 len += peer->path_attr_len_without_nexthop;
1593
1594 /* copy MP unreachable NLRI heading */
1595 memcpy(data, peer->mp_unreach_nlri_partial,
1596 BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE);
1597 /* remember where to update this attr len */
1598 unreach_len = data + 2;
1599 data += BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE;
1600 len += BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE;
1601
1602 peer->update_routes6 = 0; /* tentatively clear */
1603
1604 /* find differences */
1605 while ((have || want) && data < (max - sizeof(struct bgp_ip6_prefix)))
1606 {
1607 if (have)
1608 s = want
1609 ? memcmp(&have->dest, &want->dest, sizeof(have->dest))
1610 : -1;
1611 else
1612 s = 1;
1613
1614 if (s < 0) /* found one to delete */
1615 {
1616 struct bgp_route6_list *tmp = have;
1617 have = have->next;
1618
1619 s = BGP_IP_PREFIX_SIZE(tmp->dest);
1620 memcpy(data, &tmp->dest, s);
1621 data += s;
1622 unf_len += s;
1623 len += s;
1624
1625 LOG(5, 0, 0, "Withdrawing route %s/%d from BGP peer %s\n",
1626 inet_ntop(AF_INET6, &tmp->dest.prefix, ipv6addr, INET6_ADDRSTRLEN),
1627 tmp->dest.len, peer->name);
1628
1629 free(tmp);
1630
1631 if (e)
1632 e->next = have;
1633 else
1634 peer->routes6 = have;
1635 }
1636 else
1637 {
1638 if (!s) /* same */
1639 {
1640 e = have; /* stash the last found to relink above */
1641 have = have->next;
1642 want = want->next;
1643 }
1644 else if (s > 0) /* addition reqd. */
1645 {
1646 if (add)
1647 {
1648 peer->update_routes6 = 1; /* only one add per packet */
1649 if (!have)
1650 break;
1651 }
1652 else
1653 add = want;
1654
1655 if (want)
1656 want = want->next;
1657 }
1658 }
1659 }
1660
1661 if (have || want)
1662 peer->update_routes6 = 1; /* more to do */
1663
1664 /* anything changed? */
1665 if (!(unf_len || add))
1666 return 1;
1667
1668 /* go back and insert MP unf_len */
1669 unf_len += sizeof(struct bgp_attr_mp_unreach_nlri_partial);
1670 unf_len = htons(unf_len);
1671 memcpy(&unreach_len, &unf_len, sizeof(unf_len));
1672
1673 if (add)
1674 {
1675 if (!(e = malloc(sizeof(*e))))
1676 {
1677 LOG(0, 0, 0, "Can't allocate route for %s/%d (%s)\n",
1678 inet_ntop(AF_INET6, &add->dest.prefix, ipv6addr, INET6_ADDRSTRLEN),
1679 add->dest.len, strerror(errno));
1680
1681 return 0;
1682 }
1683
1684 memcpy(e, add, sizeof(*e));
1685 e->next = 0;
1686 peer->routes6 = bgp_insert_route6(peer->routes6, e);
1687
1688 /* copy MP reachable NLRI heading */
1689 memcpy(data, peer->mp_reach_nlri_partial,
1690 BGP_PATH_ATTR_MP_REACH_NLRI_PARTIAL_SIZE);
1691 /* with proper len */
1692 reach_len = BGP_IP_PREFIX_SIZE(add->dest);
1693 data[2] = reach_len;
1694 data += BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE;
1695 len += BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE;
1696
1697 memcpy(data, &add->dest, reach_len);
1698 data += reach_len;
1699 len += reach_len;
1700
1701 LOG(5, 0, 0, "Advertising route %s/%d to BGP peer %s\n",
1702 inet_ntop(AF_INET6, &add->dest.prefix, ipv6addr, INET6_ADDRSTRLEN),
1703 add->dest.len, peer->name);
1704 }
1705
1706 /* go back and insert attr_len */
1707 attr_len = htons(len - 4);
1708 memcpy(&peer->outbuf->packet.data + 2, &attr_len, sizeof(attr_len));
1709
1710 peer->outbuf->packet.header.len = htons(len);
1711 peer->outbuf->done = 0;
1712
1713 return bgp_write(peer);
1714 }
1715
1716 /* send/buffer NOTIFICATION message */
1717 static int bgp_send_notification(struct bgp_peer *peer, uint8_t code,
1718 uint8_t subcode)
1719 {
1720 struct bgp_data_notification data;
1721 uint16_t len = 0;
1722
1723 data.error_code = code;
1724 len += sizeof(data.error_code);
1725
1726 data.error_subcode = subcode;
1727 len += sizeof(data.error_code);
1728
1729 memset(peer->outbuf->packet.header.marker, 0xff,
1730 sizeof(peer->outbuf->packet.header.marker));
1731
1732 peer->outbuf->packet.header.type = BGP_MSG_NOTIFICATION;
1733 peer->outbuf->packet.header.len =
1734 htons(sizeof(peer->outbuf->packet.header) + len);
1735
1736 memcpy(peer->outbuf->packet.data, &data, len);
1737
1738 peer->outbuf->done = 0;
1739 peer->next_state = code == BGP_ERR_CEASE ? Disabled : Idle;
1740
1741 /* we're dying; ignore any pending input */
1742 peer->inbuf->packet.header.len = 0;
1743 peer->inbuf->done = 0;
1744
1745 return bgp_write(peer);
1746 }