Better check for IPv6 compatibility with the BGP peer.
[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(BGP_MP_AFI_IPv6);
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(BGP_MP_AFI_IPv6);
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].mp_handling == HandleIPv6Routes)
561 bgp_peers[i].update_routes6 = 1;
562
563 LOG(4, 0, 0, "Registered BGP route %s/%d\n",
564 inet_ntop(AF_INET6, &ip, ipv6addr, INET6_ADDRSTRLEN), add.dest.len);
565
566 return 1;
567 }
568
569 /* remove route from list for peers */
570 int bgp_del_route(in_addr_t ip, in_addr_t mask)
571 {
572 struct bgp_route_list *r = bgp_routes;
573 struct bgp_route_list *e = 0;
574 struct bgp_route_list del;
575 int i;
576
577 bgp_cidr(ip, mask, &del.dest);
578 del.next = 0;
579
580 /* find entry in routes list and remove */
581 while (r)
582 {
583 i = memcmp(&r->dest, &del.dest, sizeof(r->dest));
584 if (!i)
585 {
586 if (e)
587 e->next = r->next;
588 else
589 bgp_routes = r->next;
590
591 free(r);
592 break;
593 }
594
595 e = r;
596
597 if (i > 0)
598 r = 0; /* stop */
599 else
600 r = r->next;
601 }
602
603 /* not found */
604 if (!r)
605 return 1;
606
607 /* flag established peers for update */
608 for (i = 0; i < BGP_NUM_PEERS; i++)
609 if (bgp_peers[i].state == Established)
610 bgp_peers[i].update_routes = 1;
611
612 LOG(4, 0, 0, "Removed BGP route %s/%d\n",
613 fmtaddr(del.dest.prefix, 0), del.dest.len);
614
615 return 1;
616 }
617
618 /* remove route from list for peers */
619 int bgp_del_route6(struct in6_addr ip, int prefixlen)
620 {
621 struct bgp_route6_list *r = bgp_routes6;
622 struct bgp_route6_list *e = 0;
623 struct bgp_route6_list del;
624 int i;
625 char ipv6addr[INET6_ADDRSTRLEN];
626
627 memcpy(&del.dest.prefix, &ip.s6_addr, 16);
628 del.dest.len = prefixlen;
629 del.next = 0;
630
631 /* find entry in routes list and remove */
632 while (r)
633 {
634 i = memcmp(&r->dest, &del.dest, sizeof(r->dest));
635 if (!i)
636 {
637 if (e)
638 e->next = r->next;
639 else
640 bgp_routes6 = r->next;
641
642 free(r);
643 break;
644 }
645
646 e = r;
647
648 if (i > 0)
649 r = 0; /* stop */
650 else
651 r = r->next;
652 }
653
654 /* not found */
655 if (!r)
656 return 1;
657
658 /* flag established peers for update */
659 for (i = 0; i < BGP_NUM_PEERS; i++)
660 if (bgp_peers[i].state == Established
661 && bgp_peers[i].mp_handling == HandleIPv6Routes)
662 bgp_peers[i].update_routes6 = 1;
663
664 LOG(4, 0, 0, "Removed BGP route %s/%d\n",
665 inet_ntop(AF_INET6, &ip, ipv6addr, INET6_ADDRSTRLEN), del.dest.len);
666
667 return 1;
668 }
669
670 /* enable or disable routing */
671 void bgp_enable_routing(int enable)
672 {
673 int i;
674
675 for (i = 0; i < BGP_NUM_PEERS; i++)
676 {
677 bgp_peers[i].routing = enable;
678
679 /* flag established peers for update */
680 if (bgp_peers[i].state == Established)
681 bgp_peers[i].update_routes = 1;
682 }
683
684 LOG(4, 0, 0, "%s BGP routing\n", enable ? "Enabled" : "Suspended");
685 }
686
687 #ifdef HAVE_EPOLL
688 # include <sys/epoll.h>
689 #else
690 # include "fake_epoll.h"
691 #endif
692
693 /* return a bitmask of the events required to poll this peer's fd */
694 int bgp_set_poll()
695 {
696 int i;
697
698 if (!bgp_configured)
699 return 0;
700
701 for (i = 0; i < BGP_NUM_PEERS; i++)
702 {
703 struct bgp_peer *peer = &bgp_peers[i];
704 int events = 0;
705
706 if (peer->state == Disabled || peer->state == Idle)
707 continue;
708
709 if (peer->inbuf->done < BGP_MAX_PACKET_SIZE)
710 events |= EPOLLIN;
711
712 if (peer->state == Connect || /* connection in progress */
713 peer->update_routes || /* routing updates */
714 peer->outbuf->packet.header.len) /* pending output */
715 events |= EPOLLOUT;
716
717 if (peer->events != events)
718 {
719 struct epoll_event ev;
720
721 ev.events = peer->events = events;
722 ev.data.ptr = &peer->edata;
723 epoll_ctl(epollfd, EPOLL_CTL_MOD, peer->sock, &ev);
724 }
725 }
726
727 return 1;
728 }
729
730 /* process bgp events/timers */
731 int bgp_process(uint32_t events[])
732 {
733 int i;
734
735 if (!bgp_configured)
736 return 0;
737
738 for (i = 0; i < BGP_NUM_PEERS; i++)
739 {
740 struct bgp_peer *peer = &bgp_peers[i];
741
742 if (*peer->name && peer->cli_flag == BGP_CLI_RESTART)
743 {
744 bgp_restart(peer);
745 continue;
746 }
747
748 if (peer->state == Disabled)
749 continue;
750
751 if (peer->cli_flag)
752 {
753 switch (peer->cli_flag)
754 {
755 case BGP_CLI_SUSPEND:
756 if (peer->routing)
757 {
758 peer->routing = 0;
759 if (peer->state == Established)
760 peer->update_routes = 1;
761 }
762
763 break;
764
765 case BGP_CLI_ENABLE:
766 if (!peer->routing)
767 {
768 peer->routing = 1;
769 if (peer->state == Established)
770 peer->update_routes = 1;
771 }
772
773 break;
774 }
775
776 peer->cli_flag = 0;
777 }
778
779 /* handle empty/fill of buffers */
780 if (events[i] & EPOLLOUT)
781 {
782 int r = 1;
783 if (peer->state == Connect)
784 r = bgp_handle_connect(peer);
785 else if (peer->outbuf->packet.header.len)
786 r = bgp_write(peer);
787
788 if (!r)
789 continue;
790 }
791
792 if (events[i] & (EPOLLIN|EPOLLHUP))
793 {
794 if (!bgp_read(peer))
795 continue;
796 }
797
798 /* process input buffer contents */
799 while (peer->inbuf->done >= sizeof(peer->inbuf->packet.header)
800 && !peer->outbuf->packet.header.len) /* may need to queue a response */
801 {
802 if (bgp_handle_input(peer) < 0)
803 continue;
804 }
805
806 /* process pending updates */
807 if (peer->update_routes
808 && !peer->outbuf->packet.header.len) /* ditto */
809 {
810 if (!bgp_send_update(peer))
811 continue;
812 }
813
814 /* process pending IPv6 updates */
815 if (peer->update_routes6
816 && !peer->outbuf->packet.header.len) /* ditto */
817 {
818 if (!bgp_send_update6(peer))
819 continue;
820 }
821
822 /* process timers */
823 if (peer->state == Established)
824 {
825 if (time_now > peer->expire_time)
826 {
827 LOG(1, 0, 0, "No message from BGP peer %s in %ds\n",
828 peer->name, peer->hold);
829
830 bgp_send_notification(peer, BGP_ERR_HOLD_TIMER_EXP, 0);
831 continue;
832 }
833
834 if (time_now > peer->keepalive_time && !peer->outbuf->packet.header.len)
835 bgp_send_keepalive(peer);
836 }
837 else if (peer->state == Idle)
838 {
839 if (time_now > peer->retry_time)
840 bgp_connect(peer);
841 }
842 else if (time_now > peer->state_time + BGP_STATE_TIME)
843 {
844 LOG(1, 0, 0, "%s timer expired for BGP peer %s\n",
845 bgp_state_str(peer->state), peer->name);
846
847 bgp_restart(peer);
848 }
849 }
850
851 return 1;
852 }
853
854 static void bgp_free_routes(struct bgp_route_list *routes)
855 {
856 struct bgp_route_list *tmp;
857
858 while ((tmp = routes))
859 {
860 routes = tmp->next;
861 free(tmp);
862 }
863 }
864
865 static void bgp_free_routes6(struct bgp_route6_list *routes)
866 {
867 struct bgp_route6_list *tmp;
868
869 while ((tmp = routes))
870 {
871 routes = tmp->next;
872 free(tmp);
873 }
874 }
875
876 char const *bgp_state_str(enum bgp_state state)
877 {
878 switch (state)
879 {
880 case Disabled: return "Disabled";
881 case Idle: return "Idle";
882 case Connect: return "Connect";
883 case Active: return "Active";
884 case OpenSent: return "OpenSent";
885 case OpenConfirm: return "OpenConfirm";
886 case Established: return "Established";
887 }
888
889 return "?";
890 }
891
892 static char const *bgp_msg_type_str(uint8_t type)
893 {
894 switch (type)
895 {
896 case BGP_MSG_OPEN: return "OPEN";
897 case BGP_MSG_UPDATE: return "UPDATE";
898 case BGP_MSG_NOTIFICATION: return "NOTIFICATION";
899 case BGP_MSG_KEEPALIVE: return "KEEPALIVE";
900 }
901
902 return "?";
903 }
904
905 /* attempt to connect to peer */
906 static int bgp_connect(struct bgp_peer *peer)
907 {
908 static int bgp_port = 0;
909 struct sockaddr_in addr;
910 struct epoll_event ev;
911
912 if (!bgp_port)
913 {
914 struct servent *serv;
915 if (!(serv = getservbyname("bgp", "tcp")))
916 {
917 LOG(0, 0, 0, "Can't get bgp service (%s)\n", strerror(errno));
918 return 0;
919 }
920
921 bgp_port = serv->s_port;
922 }
923
924 if ((peer->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
925 {
926 LOG(0, 0, 0, "Can't create a socket for BGP peer %s (%s)\n",
927 peer->name, strerror(errno));
928
929 peer->state = peer->next_state = Disabled;
930 return 0;
931 }
932
933 /* add to poll set */
934 ev.events = peer->events = EPOLLOUT;
935 ev.data.ptr = &peer->edata;
936 epoll_ctl(epollfd, EPOLL_CTL_ADD, peer->sock, &ev);
937
938 /* set to non-blocking */
939 fcntl(peer->sock, F_SETFL, fcntl(peer->sock, F_GETFL, 0) | O_NONBLOCK);
940
941 /* try connect */
942 memset(&addr, 0, sizeof(addr));
943 addr.sin_family = AF_INET;
944 addr.sin_port = bgp_port;
945 addr.sin_addr.s_addr = peer->addr;
946
947 while (connect(peer->sock, (struct sockaddr *) &addr, sizeof(addr)) == -1)
948 {
949 if (errno == EINTR) /* SIGALARM handler */
950 continue;
951
952 if (errno != EINPROGRESS)
953 {
954 LOG(1, 0, 0, "Can't connect to BGP peer %s (%s)\n",
955 inet_ntoa(addr.sin_addr), strerror(errno));
956
957 bgp_set_retry(peer);
958 return 0;
959 }
960
961 peer->state = Connect;
962 peer->state_time = time_now;
963
964 LOG(4, 0, 0, "BGP peer %s: state Connect\n", peer->name);
965 return 1;
966 }
967
968 peer->state = Active;
969 peer->state_time = time_now;
970 peer->retry_time = peer->retry_count = 0;
971
972 LOG(4, 0, 0, "BGP peer %s: state Active\n", inet_ntoa(addr.sin_addr));
973
974 return bgp_send_open(peer);
975 }
976
977 /* complete partial connection (state = Connect) */
978 static int bgp_handle_connect(struct bgp_peer *peer)
979 {
980 int err = 0;
981 socklen_t len = sizeof(int);
982 getsockopt(peer->sock, SOL_SOCKET, SO_ERROR, &err, &len);
983 if (err)
984 {
985 LOG(1, 0, 0, "Can't connect to BGP peer %s (%s)\n", peer->name,
986 strerror(err));
987
988 bgp_set_retry(peer);
989 return 0;
990 }
991
992 peer->state = Active;
993 peer->state_time = time_now;
994
995 LOG(4, 0, 0, "BGP peer %s: state Active\n", peer->name);
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 *)((char *)&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 /* look for BGP multiprotocol capability */
1217 for (capability_offset = 0;
1218 capability_offset < capabilities_len;
1219 capability_offset += 2 + capability->len)
1220 {
1221 capability = (struct bgp_capability *)(capabilities + capability_offset);
1222
1223 /* sensible check */
1224 if (capabilities_len - capability_offset < 2
1225 || capability->len > capabilities_len - capability_offset - 2)
1226 {
1227 LOG(1, 0, 0, "Malformed Capabilities list from BGP peer %s\n",
1228 peer->name);
1229
1230 bgp_send_notification(peer, BGP_ERR_OPEN, BGP_ERR_UNSPEC);
1231 return 0;
1232 }
1233
1234 /* we only know one capability code */
1235 if (capability->code != BGP_CAP_CODE_MP
1236 && capability->len != sizeof(struct bgp_mp_cap_param))
1237 {
1238 LOG(4, 0, 0, "Unsupported Capability code %d from BGP peer %s\n",
1239 capability->code, peer->name);
1240
1241 bgp_send_notification_full(peer, BGP_ERR_OPEN, BGP_ERR_OPN_UNSUP_CAP,
1242 (char *)capability, 2 + capability->len);
1243 /* we don't terminate, still; we just jump to the next one */
1244 continue;
1245 }
1246
1247 mp_cap = (struct bgp_mp_cap_param *)&capability->value;
1248 /* the only <AFI, SAFI> tuple we support */
1249 if (ntohs(mp_cap->afi) != BGP_MP_AFI_IPv6 && mp_cap->safi != BGP_MP_SAFI_UNICAST)
1250 {
1251 LOG(4, 0, 0, "Unsupported multiprotocol AFI %d and SAFI %d from BGP peer %s\n",
1252 mp_cap->afi, mp_cap->safi, peer->name);
1253
1254 bgp_send_notification_full(peer, BGP_ERR_OPEN, BGP_ERR_OPN_UNSUP_CAP,
1255 (char *)capability, 2 + capability->len);
1256 /* we don't terminate, still; we just jump to the next one */
1257 continue;
1258 }
1259
1260 /* yes it can! */
1261 peer->mp_handling = HandleIPv6Routes;
1262 }
1263 }
1264
1265 if (peer->mp_handling != HandleIPv6Routes)
1266 {
1267 peer->mp_handling = DoesntHandleIPv6Routes;
1268 if (config->ipv6_prefix.s6_addr[0])
1269 LOG(1, 0, 0, "Warning: BGP peer %s doesn't handle IPv6 prefixes updates\n",
1270 peer->name);
1271 }
1272
1273 /* next transition requires an exchange of keepalives */
1274 bgp_send_keepalive(peer);
1275 }
1276
1277 break;
1278
1279 case BGP_MSG_KEEPALIVE:
1280 if (peer->state == OpenConfirm)
1281 {
1282 peer->state = peer->next_state = Established;
1283 peer->state_time = time_now;
1284 peer->keepalive_time = time_now + peer->keepalive;
1285 peer->update_routes = 1;
1286 peer->retry_count = 0;
1287 peer->retry_time = 0;
1288
1289 LOG(4, 0, 0, "BGP peer %s: state Established\n", peer->name);
1290 }
1291
1292 break;
1293
1294 case BGP_MSG_NOTIFICATION:
1295 if (len > sizeof(p->header))
1296 {
1297 struct bgp_data_notification *notification =
1298 (struct bgp_data_notification *) p->data;
1299
1300 if (notification->error_code == BGP_ERR_CEASE)
1301 {
1302 LOG(4, 0, 0, "BGP peer %s sent CEASE\n", peer->name);
1303 bgp_restart(peer);
1304 return 0;
1305 }
1306
1307 if (notification->error_code == BGP_ERR_OPEN
1308 && notification->error_subcode == BGP_ERR_OPN_UNSUP_PARAM)
1309 {
1310 LOG(4, 0, 0, "BGP peer %s doesn't support BGP Capabilities\n", peer->name);
1311 peer->mp_handling = DoesntHandleIPv6Routes;
1312 bgp_restart(peer);
1313 return 0;
1314 }
1315
1316 if (notification->error_code == BGP_ERR_OPEN
1317 && notification->error_subcode == BGP_ERR_OPN_UNSUP_CAP)
1318 {
1319 /* the only capability we advertise is this one, so upon receiving
1320 an "unsupported capability" message, we disable IPv6 routes for
1321 this peer */
1322 LOG(4, 0, 0, "BGP peer %s doesn't support IPv6 routes advertisement\n", peer->name);
1323 peer->mp_handling = DoesntHandleIPv6Routes;
1324 break;
1325 }
1326
1327 /* FIXME: should handle more notifications */
1328 LOG(4, 0, 0, "BGP peer %s sent unhandled NOTIFICATION %d\n",
1329 peer->name, (int) notification->error_code);
1330 }
1331
1332 break;
1333 }
1334
1335 /* reset timer */
1336 peer->expire_time = time_now + peer->hold;
1337
1338 /* see if there's another message in the same packet/buffer */
1339 if (peer->inbuf->done > len)
1340 {
1341 peer->inbuf->done -= len;
1342 memmove(p, (char *) p + len, peer->inbuf->done);
1343 }
1344 else
1345 {
1346 peer->inbuf->packet.header.len = 0;
1347 peer->inbuf->done = 0;
1348 }
1349
1350 return peer->inbuf->done;
1351 }
1352
1353 /* send/buffer OPEN message */
1354 static int bgp_send_open(struct bgp_peer *peer)
1355 {
1356 struct bgp_data_open data;
1357 struct bgp_mp_cap_param mp_ipv6 = { htons(BGP_MP_AFI_IPv6), 0, BGP_MP_SAFI_UNICAST };
1358 struct bgp_capability cap_mp_ipv6;
1359 struct bgp_opt_param param_cap_mp_ipv6;
1360 uint16_t len = sizeof(peer->outbuf->packet.header);
1361
1362 memset(peer->outbuf->packet.header.marker, 0xff,
1363 sizeof(peer->outbuf->packet.header.marker));
1364
1365 peer->outbuf->packet.header.type = BGP_MSG_OPEN;
1366
1367 data.version = BGP_VERSION;
1368 data.as = htons(our_as);
1369 data.hold_time = htons(peer->hold);
1370 data.identifier = my_address;
1371
1372 /* if we know peer doesn't support MP (mp_handling == DoesntHandleIPv6Routes)
1373 then don't add this parameter */
1374 if (config->ipv6_prefix.s6_addr[0]
1375 && (peer->mp_handling == HandlingUnknown
1376 || peer->mp_handling == HandleIPv6Routes))
1377 {
1378 /* construct the param and capability */
1379 cap_mp_ipv6.code = BGP_CAP_CODE_MP;
1380 cap_mp_ipv6.len = sizeof(mp_ipv6);
1381 memcpy(&cap_mp_ipv6.value, &mp_ipv6, cap_mp_ipv6.len);
1382
1383 param_cap_mp_ipv6.type = BGP_PARAM_TYPE_CAPABILITY;
1384 param_cap_mp_ipv6.len = 2 + sizeof(mp_ipv6);
1385 memcpy(&param_cap_mp_ipv6.value, &cap_mp_ipv6, param_cap_mp_ipv6.len);
1386
1387 data.opt_len = 2 + param_cap_mp_ipv6.len;
1388 memcpy(&data.opt_params, &param_cap_mp_ipv6, data.opt_len);
1389 }
1390 else
1391 data.opt_len = 0;
1392
1393 memcpy(peer->outbuf->packet.data, &data, BGP_DATA_OPEN_SIZE + data.opt_len);
1394 len += BGP_DATA_OPEN_SIZE + data.opt_len;
1395
1396 peer->outbuf->packet.header.len = htons(len);
1397 peer->outbuf->done = 0;
1398 peer->next_state = OpenSent;
1399
1400 return bgp_write(peer);
1401 }
1402
1403 /* send/buffer KEEPALIVE message */
1404 static int bgp_send_keepalive(struct bgp_peer *peer)
1405 {
1406 memset(peer->outbuf->packet.header.marker, 0xff,
1407 sizeof(peer->outbuf->packet.header.marker));
1408
1409 peer->outbuf->packet.header.type = BGP_MSG_KEEPALIVE;
1410 peer->outbuf->packet.header.len =
1411 htons(sizeof(peer->outbuf->packet.header));
1412
1413 peer->outbuf->done = 0;
1414 peer->next_state = (peer->state == OpenSent) ? OpenConfirm : peer->state;
1415
1416 return bgp_write(peer);
1417 }
1418
1419 /* send/buffer UPDATE message */
1420 static int bgp_send_update(struct bgp_peer *peer)
1421 {
1422 uint16_t unf_len = 0;
1423 uint16_t attr_len;
1424 uint16_t len = sizeof(peer->outbuf->packet.header);
1425 struct bgp_route_list *have = peer->routes;
1426 struct bgp_route_list *want = peer->routing ? bgp_routes : 0;
1427 struct bgp_route_list *e = 0;
1428 struct bgp_route_list *add = 0;
1429 int s;
1430
1431 char *data = (char *) &peer->outbuf->packet.data;
1432
1433 /* need leave room for attr_len, bgp_path_attrs and one prefix */
1434 char *max = (char *) &peer->outbuf->packet.data
1435 + sizeof(peer->outbuf->packet.data)
1436 - sizeof(attr_len) - peer->path_attr_len - sizeof(struct bgp_ip_prefix);
1437
1438 /* skip over unf_len */
1439 data += sizeof(unf_len);
1440 len += sizeof(unf_len);
1441
1442 memset(peer->outbuf->packet.header.marker, 0xff,
1443 sizeof(peer->outbuf->packet.header.marker));
1444
1445 peer->outbuf->packet.header.type = BGP_MSG_UPDATE;
1446
1447 peer->update_routes = 0; /* tentatively clear */
1448
1449 /* find differences */
1450 while ((have || want) && data < (max - sizeof(struct bgp_ip_prefix)))
1451 {
1452 if (have)
1453 s = want
1454 ? memcmp(&have->dest, &want->dest, sizeof(have->dest))
1455 : -1;
1456 else
1457 s = 1;
1458
1459 if (s < 0) /* found one to delete */
1460 {
1461 struct bgp_route_list *tmp = have;
1462 have = have->next;
1463
1464 s = BGP_IP_PREFIX_SIZE(tmp->dest);
1465 memcpy(data, &tmp->dest, s);
1466 data += s;
1467 unf_len += s;
1468 len += s;
1469
1470 LOG(5, 0, 0, "Withdrawing route %s/%d from BGP peer %s\n",
1471 fmtaddr(tmp->dest.prefix, 0), tmp->dest.len, peer->name);
1472
1473 free(tmp);
1474
1475 if (e)
1476 e->next = have;
1477 else
1478 peer->routes = have;
1479 }
1480 else
1481 {
1482 if (!s) /* same */
1483 {
1484 e = have; /* stash the last found to relink above */
1485 have = have->next;
1486 want = want->next;
1487 }
1488 else if (s > 0) /* addition reqd. */
1489 {
1490 if (add)
1491 {
1492 peer->update_routes = 1; /* only one add per packet */
1493 if (!have)
1494 break;
1495 }
1496 else
1497 add = want;
1498
1499 if (want)
1500 want = want->next;
1501 }
1502 }
1503 }
1504
1505 if (have || want)
1506 peer->update_routes = 1; /* more to do */
1507
1508 /* anything changed? */
1509 if (!(unf_len || add))
1510 return 1;
1511
1512 /* go back and insert unf_len */
1513 unf_len = htons(unf_len);
1514 memcpy(&peer->outbuf->packet.data, &unf_len, sizeof(unf_len));
1515
1516 if (add)
1517 {
1518 if (!(e = malloc(sizeof(*e))))
1519 {
1520 LOG(0, 0, 0, "Can't allocate route for %s/%d (%s)\n",
1521 fmtaddr(add->dest.prefix, 0), add->dest.len, strerror(errno));
1522
1523 return 0;
1524 }
1525
1526 memcpy(e, add, sizeof(*e));
1527 e->next = 0;
1528 peer->routes = bgp_insert_route(peer->routes, e);
1529
1530 attr_len = htons(peer->path_attr_len);
1531 memcpy(data, &attr_len, sizeof(attr_len));
1532 data += sizeof(attr_len);
1533 len += sizeof(attr_len);
1534
1535 memcpy(data, peer->path_attrs, peer->path_attr_len);
1536 data += peer->path_attr_len;
1537 len += peer->path_attr_len;
1538
1539 s = BGP_IP_PREFIX_SIZE(add->dest);
1540 memcpy(data, &add->dest, s);
1541 data += s;
1542 len += s;
1543
1544 LOG(5, 0, 0, "Advertising route %s/%d to BGP peer %s\n",
1545 fmtaddr(add->dest.prefix, 0), add->dest.len, peer->name);
1546 }
1547 else
1548 {
1549 attr_len = 0;
1550 memcpy(data, &attr_len, sizeof(attr_len));
1551 data += sizeof(attr_len);
1552 len += sizeof(attr_len);
1553 }
1554
1555 peer->outbuf->packet.header.len = htons(len);
1556 peer->outbuf->done = 0;
1557
1558 return bgp_write(peer);
1559 }
1560
1561 /* send/buffer UPDATE message for IPv6 routes */
1562 static int bgp_send_update6(struct bgp_peer *peer)
1563 {
1564 uint16_t unf_len = 0;
1565 uint16_t attr_len;
1566 char *unreach_len;
1567 uint8_t reach_len;
1568 uint16_t len = sizeof(peer->outbuf->packet.header);
1569 struct bgp_route6_list *have = peer->routes6;
1570 struct bgp_route6_list *want = peer->routing ? bgp_routes6 : 0;
1571 struct bgp_route6_list *e = 0;
1572 struct bgp_route6_list *add = 0;
1573 int s;
1574 char ipv6addr[INET6_ADDRSTRLEN];
1575
1576 char *data = (char *) &peer->outbuf->packet.data;
1577
1578 /* need leave room for attr_len, bgp_path_attrs and one prefix */
1579 char *max = (char *) &peer->outbuf->packet.data
1580 + sizeof(peer->outbuf->packet.data)
1581 - sizeof(attr_len) - peer->path_attr_len_without_nexthop
1582 - BGP_PATH_ATTR_MP_REACH_NLRI_PARTIAL_SIZE - sizeof(struct bgp_ip6_prefix);
1583
1584 memset(peer->outbuf->packet.header.marker, 0xff,
1585 sizeof(peer->outbuf->packet.header.marker));
1586
1587 peer->outbuf->packet.header.type = BGP_MSG_UPDATE;
1588
1589 /* insert non-MP unf_len */
1590 memcpy(data, &unf_len, sizeof(unf_len));
1591 /* skip over attr_len too; will be filled when known */
1592 data += sizeof(unf_len) + sizeof(attr_len);
1593 len += sizeof(unf_len) + sizeof(attr_len);
1594
1595 /* copy usual attributes */
1596 memcpy(data, peer->path_attrs, peer->path_attr_len_without_nexthop);
1597 data += peer->path_attr_len_without_nexthop;
1598 len += peer->path_attr_len_without_nexthop;
1599
1600 /* copy MP unreachable NLRI heading */
1601 memcpy(data, peer->mp_unreach_nlri_partial,
1602 BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE);
1603 /* remember where to update this attr len */
1604 unreach_len = data + 2;
1605 data += BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE;
1606 len += BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE;
1607
1608 peer->update_routes6 = 0; /* tentatively clear */
1609
1610 /* find differences */
1611 while ((have || want) && data < (max - sizeof(struct bgp_ip6_prefix)))
1612 {
1613 if (have)
1614 s = want
1615 ? memcmp(&have->dest, &want->dest, sizeof(have->dest))
1616 : -1;
1617 else
1618 s = 1;
1619
1620 if (s < 0) /* found one to delete */
1621 {
1622 struct bgp_route6_list *tmp = have;
1623 have = have->next;
1624
1625 s = BGP_IP_PREFIX_SIZE(tmp->dest);
1626 memcpy(data, &tmp->dest, s);
1627 data += s;
1628 unf_len += s;
1629 len += s;
1630
1631 LOG(5, 0, 0, "Withdrawing route %s/%d from BGP peer %s\n",
1632 inet_ntop(AF_INET6, &tmp->dest.prefix, ipv6addr, INET6_ADDRSTRLEN),
1633 tmp->dest.len, peer->name);
1634
1635 free(tmp);
1636
1637 if (e)
1638 e->next = have;
1639 else
1640 peer->routes6 = have;
1641 }
1642 else
1643 {
1644 if (!s) /* same */
1645 {
1646 e = have; /* stash the last found to relink above */
1647 have = have->next;
1648 want = want->next;
1649 }
1650 else if (s > 0) /* addition reqd. */
1651 {
1652 if (add)
1653 {
1654 peer->update_routes6 = 1; /* only one add per packet */
1655 if (!have)
1656 break;
1657 }
1658 else
1659 add = want;
1660
1661 if (want)
1662 want = want->next;
1663 }
1664 }
1665 }
1666
1667 if (have || want)
1668 peer->update_routes6 = 1; /* more to do */
1669
1670 /* anything changed? */
1671 if (!(unf_len || add))
1672 return 1;
1673
1674 /* go back and insert MP unf_len */
1675 unf_len += sizeof(struct bgp_attr_mp_unreach_nlri_partial);
1676 unf_len = htons(unf_len);
1677 memcpy(&unreach_len, &unf_len, sizeof(unf_len));
1678
1679 if (add)
1680 {
1681 if (!(e = malloc(sizeof(*e))))
1682 {
1683 LOG(0, 0, 0, "Can't allocate route for %s/%d (%s)\n",
1684 inet_ntop(AF_INET6, &add->dest.prefix, ipv6addr, INET6_ADDRSTRLEN),
1685 add->dest.len, strerror(errno));
1686
1687 return 0;
1688 }
1689
1690 memcpy(e, add, sizeof(*e));
1691 e->next = 0;
1692 peer->routes6 = bgp_insert_route6(peer->routes6, e);
1693
1694 /* copy MP reachable NLRI heading */
1695 memcpy(data, peer->mp_reach_nlri_partial,
1696 BGP_PATH_ATTR_MP_REACH_NLRI_PARTIAL_SIZE);
1697 /* with proper len */
1698 reach_len = BGP_IP_PREFIX_SIZE(add->dest);
1699 data[2] = reach_len;
1700 data += BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE;
1701 len += BGP_PATH_ATTR_MP_UNREACH_NLRI_PARTIAL_SIZE;
1702
1703 memcpy(data, &add->dest, reach_len);
1704 data += reach_len;
1705 len += reach_len;
1706
1707 LOG(5, 0, 0, "Advertising route %s/%d to BGP peer %s\n",
1708 inet_ntop(AF_INET6, &add->dest.prefix, ipv6addr, INET6_ADDRSTRLEN),
1709 add->dest.len, peer->name);
1710 }
1711
1712 /* go back and insert attr_len */
1713 attr_len = htons(len - 4);
1714 memcpy(&peer->outbuf->packet.data + 2, &attr_len, sizeof(attr_len));
1715
1716 peer->outbuf->packet.header.len = htons(len);
1717 peer->outbuf->done = 0;
1718
1719 return bgp_write(peer);
1720 }
1721
1722 /* send/buffer NOTIFICATION message */
1723 static int bgp_send_notification(struct bgp_peer *peer, uint8_t code,
1724 uint8_t subcode)
1725 {
1726 return bgp_send_notification_full(peer, code, subcode, NULL, 0);
1727 }
1728
1729 static int bgp_send_notification_full(struct bgp_peer *peer, uint8_t code,
1730 uint8_t subcode, char *notification_data, uint16_t data_len)
1731 {
1732 struct bgp_data_notification data;
1733 uint16_t len = 0;
1734
1735 data.error_code = code;
1736 len += sizeof(data.error_code);
1737
1738 data.error_subcode = subcode;
1739 len += sizeof(data.error_code);
1740
1741 memcpy(data.data, notification_data, data_len);
1742 len += data_len;
1743
1744 memset(peer->outbuf->packet.header.marker, 0xff,
1745 sizeof(peer->outbuf->packet.header.marker));
1746
1747 peer->outbuf->packet.header.type = BGP_MSG_NOTIFICATION;
1748 peer->outbuf->packet.header.len =
1749 htons(sizeof(peer->outbuf->packet.header) + len);
1750
1751 memcpy(peer->outbuf->packet.data, &data, len);
1752
1753 peer->outbuf->done = 0;
1754 peer->next_state = code == BGP_ERR_CEASE ? Disabled : Idle;
1755
1756 /* we're dying; ignore any pending input */
1757 peer->inbuf->packet.header.len = 0;
1758 peer->inbuf->done = 0;
1759
1760 return bgp_write(peer);
1761 }