Statistics
| Branch: | Revision:

iof-bird-daemon / proto / bgp / bgp.c @ 153f02da

History | View | Annotate | Download (56.1 KB)

1 2638249d Martin Mares
/*
2
 *        BIRD -- The Border Gateway Protocol
3
 *
4
 *        (c) 2000 Martin Mares <mj@ucw.cz>
5 d15b0b0a Ondrej Zajicek (work)
 *        (c) 2008--2016 Ondrej Zajicek <santiago@crfreenet.org>
6
 *        (c) 2008--2016 CZ.NIC z.s.p.o.
7 2638249d Martin Mares
 *
8
 *        Can be freely distributed and used under the terms of the GNU GPL.
9
 */
10
11 54e55169 Martin Mares
/**
12
 * DOC: Border Gateway Protocol
13
 *
14 d15b0b0a Ondrej Zajicek (work)
 * The BGP protocol is implemented in three parts: |bgp.c| which takes care of
15
 * the connection and most of the interface with BIRD core, |packets.c| handling
16 54e55169 Martin Mares
 * both incoming and outgoing BGP packets and |attrs.c| containing functions for
17
 * manipulation with BGP attribute lists.
18
 *
19 d15b0b0a Ondrej Zajicek (work)
 * As opposed to the other existing routing daemons, BIRD has a sophisticated
20
 * core architecture which is able to keep all the information needed by BGP in
21
 * the primary routing table, therefore no complex data structures like a
22
 * central BGP table are needed. This increases memory footprint of a BGP router
23
 * with many connections, but not too much and, which is more important, it
24
 * makes BGP much easier to implement.
25 54e55169 Martin Mares
 *
26 d15b0b0a Ondrej Zajicek (work)
 * Each instance of BGP (corresponding to a single BGP peer) is described by a
27
 * &bgp_proto structure to which are attached individual connections represented
28
 * by &bgp_connection (usually, there exists only one connection, but during BGP
29
 * session setup, there can be more of them). The connections are handled
30
 * according to the BGP state machine defined in the RFC with all the timers and
31
 * all the parameters configurable.
32 54e55169 Martin Mares
 *
33 d15b0b0a Ondrej Zajicek (work)
 * In incoming direction, we listen on the connection's socket and each time we
34
 * receive some input, we pass it to bgp_rx(). It decodes packet headers and the
35
 * markers and passes complete packets to bgp_rx_packet() which distributes the
36
 * packet according to its type.
37 54e55169 Martin Mares
 *
38 d15b0b0a Ondrej Zajicek (work)
 * In outgoing direction, we gather all the routing updates and sort them to
39
 * buckets (&bgp_bucket) according to their attributes (we keep a hash table for
40
 * fast comparison of &rta's and a &fib which helps us to find if we already
41
 * have another route for the same destination queued for sending, so that we
42
 * can replace it with the new one immediately instead of sending both
43
 * updates). There also exists a special bucket holding all the route
44
 * withdrawals which cannot be queued anywhere else as they don't have any
45
 * attributes. If we have any packet to send (due to either new routes or the
46
 * connection tracking code wanting to send a Open, Keepalive or Notification
47
 * message), we call bgp_schedule_packet() which sets the corresponding bit in a
48
 * @packet_to_send bit field in &bgp_conn and as soon as the transmit socket
49
 * buffer becomes empty, we call bgp_fire_tx(). It inspects state of all the
50
 * packet type bits and calls the corresponding bgp_create_xx() functions,
51
 * eventually rescheduling the same packet type if we have more data of the same
52
 * type to send.
53 54e55169 Martin Mares
 *
54 d15b0b0a Ondrej Zajicek (work)
 * The processing of attributes consists of two functions: bgp_decode_attrs()
55
 * for checking of the attribute blocks and translating them to the language of
56
 * BIRD's extended attributes and bgp_encode_attrs() which does the
57
 * converse. Both functions are built around a @bgp_attr_table array describing
58
 * all important characteristics of all known attributes.  Unknown transitive
59
 * attributes are attached to the route as %EAF_TYPE_OPAQUE byte streams.
60 6eda3f13 Ondrej Zajicek
 *
61
 * BGP protocol implements graceful restart in both restarting (local restart)
62
 * and receiving (neighbor restart) roles. The first is handled mostly by the
63
 * graceful restart code in the nest, BGP protocol just handles capabilities,
64
 * sets @gr_wait and locks graceful restart until end-of-RIB mark is received.
65
 * The second is implemented by internal restart of the BGP state to %BS_IDLE
66
 * and protocol state to %PS_START, but keeping the protocol up from the core
67
 * point of view and therefore maintaining received routes. Routing table
68
 * refresh cycle (rt_refresh_begin(), rt_refresh_end()) is used for removing
69
 * stale routes after reestablishment of BGP session during graceful restart.
70 c49e4a65 Ondrej Zajicek (work)
 *
71
 * Supported standards:
72
 * <itemize>
73
 * <item> <rfc id="4271"> - Border Gateway Protocol 4 (BGP)
74
 * <item> <rfc id="1997"> - BGP Communities Attribute
75
 * <item> <rfc id="2385"> - Protection of BGP Sessions via TCP MD5 Signature
76
 * <item> <rfc id="2545"> - Use of BGP Multiprotocol Extensions for IPv6
77
 * <item> <rfc id="2918"> - Route Refresh Capability
78
 * <item> <rfc id="3107"> - Carrying Label Information in BGP
79
 * <item> <rfc id="4360"> - BGP Extended Communities Attribute
80
 * <item> <rfc id="4364"> - BGP/MPLS IPv4 Virtual Private Networks
81
 * <item> <rfc id="4456"> - BGP Route Reflection
82
 * <item> <rfc id="4486"> - Subcodes for BGP Cease Notification Message
83
 * <item> <rfc id="4659"> - BGP/MPLS IPv6 Virtual Private Networks
84
 * <item> <rfc id="4724"> - Graceful Restart Mechanism for BGP
85
 * <item> <rfc id="4760"> - Multiprotocol extensions for BGP
86
 * <item> <rfc id="4798"> - Connecting IPv6 Islands over IPv4 MPLS
87
 * <item> <rfc id="5065"> - AS confederations for BGP
88
 * <item> <rfc id="5082"> - Generalized TTL Security Mechanism
89
 * <item> <rfc id="5492"> - Capabilities Advertisement with BGP
90
 * <item> <rfc id="5549"> - Advertising IPv4 NLRI with an IPv6 Next Hop
91
 * <item> <rfc id="5575"> - Dissemination of Flow Specification Rules
92
 * <item> <rfc id="5668"> - 4-Octet AS Specific BGP Extended Community
93
 * <item> <rfc id="6286"> - AS-Wide Unique BGP Identifier
94
 * <item> <rfc id="6608"> - Subcodes for BGP Finite State Machine Error
95
 * <item> <rfc id="6793"> - BGP Support for 4-Octet AS Numbers
96
 * <item> <rfc id="7313"> - Enhanced Route Refresh Capability for BGP
97
 * <item> <rfc id="7606"> - Revised Error Handling for BGP UPDATE Messages
98
 * <item> <rfc id="7911"> - Advertisement of Multiple Paths in BGP
99
 * <item> <rfc id="7947"> - Internet Exchange BGP Route Server
100
 * <item> <rfc id="8092"> - BGP Large Communities Attribute
101
 * </itemize>
102
*/
103 54e55169 Martin Mares
104 48d79d52 Ondrej Zajicek
#undef LOCAL_DEBUG
105 2638249d Martin Mares
106
#include "nest/bird.h"
107
#include "nest/iface.h"
108
#include "nest/protocol.h"
109
#include "nest/route.h"
110 b8113a5e Ondrej Zajicek
#include "nest/cli.h"
111 1ec52253 Ondrej Zajicek
#include "nest/locks.h"
112 2638249d Martin Mares
#include "conf/conf.h"
113 c01e3741 Martin Mares
#include "lib/socket.h"
114 973399ae Martin Mares
#include "lib/resource.h"
115 7d875e09 Martin Mares
#include "lib/string.h"
116 2638249d Martin Mares
117
#include "bgp.h"
118
119 e7d2ac44 Ondrej Zajicek
120 973399ae Martin Mares
struct linpool *bgp_linpool;                /* Global temporary pool */
121 1e37e35c Ondrej Zajicek (work)
struct linpool *bgp_linpool2;                /* Global temporary pool for bgp_rt_notify() */
122 d15b0b0a Ondrej Zajicek (work)
static list bgp_sockets;                /* Global list of listening sockets */
123
124 c01e3741 Martin Mares
125
static void bgp_connect(struct bgp_proto *p);
126 dd91e467 Ondrej Zajicek
static void bgp_active(struct bgp_proto *p);
127 1ec52253 Ondrej Zajicek
static void bgp_update_bfd(struct bgp_proto *p, int use_bfd);
128 2638249d Martin Mares
129 d15b0b0a Ondrej Zajicek (work)
static int bgp_incoming_connection(sock *sk, uint dummy UNUSED);
130
static void bgp_listen_sock_err(sock *sk UNUSED, int err);
131 11cb6202 Ondrej Zajicek
132 11b32d91 Ondrej Zajicek
/**
133
 * bgp_open - open a BGP instance
134
 * @p: BGP instance
135
 *
136 d15b0b0a Ondrej Zajicek (work)
 * This function allocates and configures shared BGP resources, mainly listening
137
 * sockets. Should be called as the last step during initialization (when lock
138
 * is acquired and neighbor is ready). When error, caller should change state to
139
 * PS_DOWN and return immediately.
140 11b32d91 Ondrej Zajicek
 */
141
static int
142
bgp_open(struct bgp_proto *p)
143
{
144 d15b0b0a Ondrej Zajicek (work)
  struct bgp_socket *bs = NULL;
145
  struct iface *ifa = p->cf->strict_bind ? p->cf->iface : NULL;
146
  ip_addr addr = p->cf->strict_bind ? p->cf->local_ip :
147
    (ipa_is_ip4(p->cf->remote_ip) ? IPA_NONE4 : IPA_NONE6);
148
  uint port = p->cf->local_port;
149
150
  /* FIXME: Add some global init? */
151
  if (!bgp_linpool)
152
    init_list(&bgp_sockets);
153 b1b19433 Ondrej Zajicek
154 d15b0b0a Ondrej Zajicek (work)
  /* We assume that cf->iface is defined iff cf->local_ip is link-local */
155 11b32d91 Ondrej Zajicek
156 d15b0b0a Ondrej Zajicek (work)
  WALK_LIST(bs, bgp_sockets)
157
    if (ipa_equal(bs->sk->saddr, addr) && (bs->sk->iface == ifa) && (bs->sk->sport == port))
158 a34b0934 Ondrej Zajicek
    {
159 d15b0b0a Ondrej Zajicek (work)
      bs->uc++;
160
      p->sock = bs;
161
      return 0;
162 a34b0934 Ondrej Zajicek
    }
163
164 d15b0b0a Ondrej Zajicek (work)
  sock *sk = sk_new(proto_pool);
165
  sk->type = SK_TCP_PASSIVE;
166
  sk->ttl = 255;
167
  sk->saddr = addr;
168
  sk->sport = port;
169
  sk->flags = 0;
170
  sk->tos = IP_PREC_INTERNET_CONTROL;
171
  sk->rbsize = BGP_RX_BUFFER_SIZE;
172
  sk->tbsize = BGP_TX_BUFFER_SIZE;
173
  sk->rx_hook = bgp_incoming_connection;
174
  sk->err_hook = bgp_listen_sock_err;
175
176
  if (sk_open(sk) < 0)
177
    goto err;
178 11b32d91 Ondrej Zajicek
179 d15b0b0a Ondrej Zajicek (work)
  bs = mb_allocz(proto_pool, sizeof(struct bgp_socket));
180
  bs->sk = sk;
181
  bs->uc = 1;
182
  p->sock = bs;
183 05476c4d Ondrej Zajicek
184 d15b0b0a Ondrej Zajicek (work)
  add_tail(&bgp_sockets, &bs->n);
185
186
  if (!bgp_linpool)
187 1e37e35c Ondrej Zajicek (work)
  {
188 05d47bd5 Jan Moskyto Matejka
    bgp_linpool  = lp_new_default(proto_pool);
189
    bgp_linpool2 = lp_new_default(proto_pool);
190 1e37e35c Ondrej Zajicek (work)
  }
191 11b32d91 Ondrej Zajicek
192
  return 0;
193 b1b19433 Ondrej Zajicek
194
err:
195 d15b0b0a Ondrej Zajicek (work)
  sk_log_error(sk, p->p.name);
196
  log(L_ERR "%s: Cannot open listening socket", p->p.name);
197
  rfree(sk);
198 b1b19433 Ondrej Zajicek
  return -1;
199 11b32d91 Ondrej Zajicek
}
200
201 d15b0b0a Ondrej Zajicek (work)
/**
202
 * bgp_close - close a BGP instance
203
 * @p: BGP instance
204
 *
205
 * This function frees and deconfigures shared BGP resources.
206
 */
207
static void
208
bgp_close(struct bgp_proto *p)
209
{
210
  struct bgp_socket *bs = p->sock;
211
212
  ASSERT(bs && bs->uc);
213
214
  if (--bs->uc)
215
    return;
216
217
  rfree(bs->sk);
218
  rem_node(&bs->n);
219
  mb_free(bs);
220
221
  if (!EMPTY_LIST(bgp_sockets))
222
    return;
223
224
  rfree(bgp_linpool);
225
  bgp_linpool = NULL;
226 1e37e35c Ondrej Zajicek (work)
227
  rfree(bgp_linpool2);
228
  bgp_linpool2 = NULL;
229 d15b0b0a Ondrej Zajicek (work)
}
230
231
static inline int
232
bgp_setup_auth(struct bgp_proto *p, int enable)
233
{
234
  if (p->cf->password)
235
  {
236
    int rv = sk_set_md5_auth(p->sock->sk,
237
                             p->cf->local_ip, p->cf->remote_ip, p->cf->iface,
238
                             enable ? p->cf->password : NULL, p->cf->setkey);
239
240
    if (rv < 0)
241
      sk_log_error(p->sock->sk, p->p.name);
242
243
    return rv;
244
  }
245
  else
246
    return 0;
247
}
248
249
static inline struct bgp_channel *
250
bgp_find_channel(struct bgp_proto *p, u32 afi)
251
{
252
  struct bgp_channel *c;
253
  WALK_LIST(c, p->p.channels)
254
    if (c->afi == afi)
255
      return c;
256
257
  return NULL;
258
}
259
260 dd91e467 Ondrej Zajicek
static void
261
bgp_startup(struct bgp_proto *p)
262
{
263
  BGP_TRACE(D_EVENTS, "Started");
264 d15b0b0a Ondrej Zajicek (work)
  p->start_state = BSS_CONNECT;
265 be6e39eb Ondrej Zajicek
266
  if (!p->cf->passive)
267
    bgp_active(p);
268 dd91e467 Ondrej Zajicek
}
269
270
static void
271
bgp_startup_timeout(timer *t)
272
{
273
  bgp_startup(t->data);
274
}
275
276
277
static void
278
bgp_initiate(struct bgp_proto *p)
279
{
280 d15b0b0a Ondrej Zajicek (work)
  int err_val;
281
282
  if (bgp_open(p) < 0)
283
  { err_val = BEM_NO_SOCKET; goto err1; }
284
285
  if (bgp_setup_auth(p, 1) < 0)
286
  { err_val = BEM_INVALID_MD5; goto err2; }
287 9be9a264 Ondrej Zajicek
288 1ec52253 Ondrej Zajicek
  if (p->cf->bfd)
289
    bgp_update_bfd(p, p->cf->bfd);
290
291 dd91e467 Ondrej Zajicek
  if (p->startup_delay)
292 d15b0b0a Ondrej Zajicek (work)
  {
293
    p->start_state = BSS_DELAY;
294
    BGP_TRACE(D_EVENTS, "Startup delayed by %d seconds due to errors", p->startup_delay);
295
    bgp_start_timer(p->startup_timer, p->startup_delay);
296
  }
297 dd91e467 Ondrej Zajicek
  else
298
    bgp_startup(p);
299
300 d15b0b0a Ondrej Zajicek (work)
  return;
301 d51aa281 Ondrej Zajicek
302 d15b0b0a Ondrej Zajicek (work)
err2:
303
  bgp_close(p);
304
err1:
305
  p->p.disabled = 1;
306
  bgp_store_error(p, NULL, BE_MISC, err_val);
307
  proto_notify_state(&p->p, PS_DOWN);
308 d51aa281 Ondrej Zajicek
309 d15b0b0a Ondrej Zajicek (work)
  return;
310 c01e3741 Martin Mares
}
311
312 54e55169 Martin Mares
/**
313
 * bgp_start_timer - start a BGP timer
314
 * @t: timer
315
 * @value: time to fire (0 to disable the timer)
316
 *
317 d15b0b0a Ondrej Zajicek (work)
 * This functions calls tm_start() on @t with time @value and the amount of
318
 * randomization suggested by the BGP standard. Please use it for all BGP
319
 * timers.
320 54e55169 Martin Mares
 */
321 3fdbafb6 Martin Mares
void
322 c01e3741 Martin Mares
bgp_start_timer(timer *t, int value)
323
{
324 3fdbafb6 Martin Mares
  if (value)
325 d15b0b0a Ondrej Zajicek (work)
  {
326
    /* The randomization procedure is specified in RFC 1771: 9.2.3.3 */
327
    t->randomize = value / 4;
328
    tm_start(t, value - t->randomize);
329
  }
330 b552ecc4 Martin Mares
  else
331
    tm_stop(t);
332
}
333
334 54e55169 Martin Mares
/**
335
 * bgp_close_conn - close a BGP connection
336
 * @conn: connection to close
337
 *
338 d15b0b0a Ondrej Zajicek (work)
 * This function takes a connection described by the &bgp_conn structure, closes
339
 * its socket and frees all resources associated with it.
340 54e55169 Martin Mares
 */
341 b552ecc4 Martin Mares
void
342
bgp_close_conn(struct bgp_conn *conn)
343
{
344 e81b440f Ondrej Zajicek
  // struct bgp_proto *p = conn->bgp;
345 b552ecc4 Martin Mares
346
  DBG("BGP: Closing connection\n");
347
  conn->packets_to_send = 0;
348 d15b0b0a Ondrej Zajicek (work)
  conn->channels_to_send = 0;
349
  rfree(conn->connect_timer);
350
  conn->connect_timer = NULL;
351 b552ecc4 Martin Mares
  rfree(conn->keepalive_timer);
352
  conn->keepalive_timer = NULL;
353
  rfree(conn->hold_timer);
354
  conn->hold_timer = NULL;
355 11b32d91 Ondrej Zajicek
  rfree(conn->tx_ev);
356
  conn->tx_ev = NULL;
357 d15b0b0a Ondrej Zajicek (work)
  rfree(conn->sk);
358
  conn->sk = NULL;
359
360
  mb_free(conn->local_caps);
361
  conn->local_caps = NULL;
362
  mb_free(conn->remote_caps);
363
  conn->remote_caps = NULL;
364 11b32d91 Ondrej Zajicek
}
365
366
367
/**
368
 * bgp_update_startup_delay - update a startup delay
369
 * @p: BGP instance
370
 *
371 d15b0b0a Ondrej Zajicek (work)
 * This function updates a startup delay that is used to postpone next BGP
372
 * connect. It also handles disable_after_error and might stop BGP instance
373
 * when error happened and disable_after_error is on.
374 11b32d91 Ondrej Zajicek
 *
375
 * It should be called when BGP protocol error happened.
376
 */
377
void
378 b99d3786 Ondrej Zajicek
bgp_update_startup_delay(struct bgp_proto *p)
379 11b32d91 Ondrej Zajicek
{
380
  struct bgp_config *cf = p->cf;
381
382 b99d3786 Ondrej Zajicek
  DBG("BGP: Updating startup delay\n");
383 11b32d91 Ondrej Zajicek
384 e81b440f Ondrej Zajicek
  if (p->last_proto_error && ((now - p->last_proto_error) >= (int) cf->error_amnesia_time))
385 72382626 Ondrej Zajicek
    p->startup_delay = 0;
386
387 11b32d91 Ondrej Zajicek
  p->last_proto_error = now;
388
389
  if (cf->disable_after_error)
390 d15b0b0a Ondrej Zajicek (work)
  {
391
    p->startup_delay = 0;
392
    p->p.disabled = 1;
393
    return;
394
  }
395 11b32d91 Ondrej Zajicek
396
  if (!p->startup_delay)
397
    p->startup_delay = cf->error_delay_time_min;
398
  else
399 b99d3786 Ondrej Zajicek
    p->startup_delay = MIN(2 * p->startup_delay, cf->error_delay_time_max);
400 c01e3741 Martin Mares
}
401
402 11b32d91 Ondrej Zajicek
static void
403 d15b0b0a Ondrej Zajicek (work)
bgp_graceful_close_conn(struct bgp_conn *conn, uint subcode)
404 48e842cc Martin Mares
{
405 11b32d91 Ondrej Zajicek
  switch (conn->state)
406 d15b0b0a Ondrej Zajicek (work)
  {
407
  case BS_IDLE:
408
  case BS_CLOSE:
409
    return;
410
411
  case BS_CONNECT:
412
  case BS_ACTIVE:
413
    bgp_conn_enter_idle_state(conn);
414
    return;
415
416
  case BS_OPENSENT:
417
  case BS_OPENCONFIRM:
418
  case BS_ESTABLISHED:
419
    bgp_error(conn, 6, subcode, NULL, 0);
420
    return;
421
422
  default:
423
    bug("bgp_graceful_close_conn: Unknown state %d", conn->state);
424
  }
425 48e842cc Martin Mares
}
426
427 c01e3741 Martin Mares
static void
428 11b32d91 Ondrej Zajicek
bgp_down(struct bgp_proto *p)
429
{
430
  if (p->start_state > BSS_PREPARE)
431 d15b0b0a Ondrej Zajicek (work)
  {
432
    bgp_setup_auth(p, 0);
433
    bgp_close(p);
434
  }
435 11b32d91 Ondrej Zajicek
436 b99d3786 Ondrej Zajicek
  BGP_TRACE(D_EVENTS, "Down");
437 11b32d91 Ondrej Zajicek
  proto_notify_state(&p->p, PS_DOWN);
438
}
439
440
static void
441
bgp_decision(void *vp)
442
{
443
  struct bgp_proto *p = vp;
444
445
  DBG("BGP: Decision start\n");
446 d15b0b0a Ondrej Zajicek (work)
  if ((p->p.proto_state == PS_START) &&
447
      (p->outgoing_conn.state == BS_IDLE) &&
448
      (p->incoming_conn.state != BS_OPENCONFIRM) &&
449
      !p->cf->passive)
450 dd91e467 Ondrej Zajicek
    bgp_active(p);
451 11b32d91 Ondrej Zajicek
452 d15b0b0a Ondrej Zajicek (work)
  if ((p->p.proto_state == PS_STOP) &&
453
      (p->outgoing_conn.state == BS_IDLE) &&
454
      (p->incoming_conn.state == BS_IDLE))
455 11b32d91 Ondrej Zajicek
    bgp_down(p);
456
}
457
458 b99d3786 Ondrej Zajicek
void
459 d15b0b0a Ondrej Zajicek (work)
bgp_stop(struct bgp_proto *p, uint subcode)
460 11b32d91 Ondrej Zajicek
{
461
  proto_notify_state(&p->p, PS_STOP);
462 b99d3786 Ondrej Zajicek
  bgp_graceful_close_conn(&p->outgoing_conn, subcode);
463
  bgp_graceful_close_conn(&p->incoming_conn, subcode);
464 11b32d91 Ondrej Zajicek
  ev_schedule(p->event);
465
}
466
467 cf31112f Ondrej Zajicek
static inline void
468 d15b0b0a Ondrej Zajicek (work)
bgp_conn_set_state(struct bgp_conn *conn, uint new_state)
469 cf31112f Ondrej Zajicek
{
470
  if (conn->bgp->p.mrtdump & MD_STATES)
471
    mrt_dump_bgp_state_change(conn, conn->state, new_state);
472
473
  conn->state = new_state;
474
}
475
476
void
477
bgp_conn_enter_openconfirm_state(struct bgp_conn *conn)
478
{
479
  /* Really, most of the work is done in bgp_rx_open(). */
480
  bgp_conn_set_state(conn, BS_OPENCONFIRM);
481
}
482
483 d15b0b0a Ondrej Zajicek (work)
static const struct bgp_af_caps dummy_af_caps = { };
484
485 11b32d91 Ondrej Zajicek
void
486
bgp_conn_enter_established_state(struct bgp_conn *conn)
487
{
488
  struct bgp_proto *p = conn->bgp;
489 d15b0b0a Ondrej Zajicek (work)
  struct bgp_caps *local = conn->local_caps;
490
  struct bgp_caps *peer = conn->remote_caps;
491
  struct bgp_channel *c;
492 523f020b Ondrej Zajicek
493 11b32d91 Ondrej Zajicek
  BGP_TRACE(D_EVENTS, "BGP session established");
494
495 9be9a264 Ondrej Zajicek
  /* For multi-hop BGP sessions */
496
  if (ipa_zero(p->source_addr))
497 0c791f87 Ondrej Zajicek
    p->source_addr = conn->sk->saddr;
498 9be9a264 Ondrej Zajicek
499 9e7b3ebd Ondrej Zajicek (work)
  conn->sk->fast_rx = 0;
500
501 11b32d91 Ondrej Zajicek
  p->conn = conn;
502
  p->last_error_class = 0;
503
  p->last_error_code = 0;
504 094d2bdb Ondrej Zajicek
505 d15b0b0a Ondrej Zajicek (work)
  p->as4_session = conn->as4_session;
506
507
  p->route_refresh = peer->route_refresh;
508
  p->enhanced_refresh = local->enhanced_refresh && peer->enhanced_refresh;
509 0c791f87 Ondrej Zajicek
510 d15b0b0a Ondrej Zajicek (work)
  /* Whether we may handle possible GR of peer (it has some AF GR-able) */
511
  p->gr_ready = 0;        /* Updated later */
512 0c791f87 Ondrej Zajicek
513 d15b0b0a Ondrej Zajicek (work)
  /* Whether peer is ready to handle our GR recovery */
514
  int peer_gr_ready = peer->gr_aware && !(peer->gr_flags & BGP_GRF_RESTART);
515 0c791f87 Ondrej Zajicek
516 d15b0b0a Ondrej Zajicek (work)
  if (p->gr_active_num)
517 0c791f87 Ondrej Zajicek
    tm_stop(p->gr_timer);
518
519 d15b0b0a Ondrej Zajicek (work)
  /* Number of active channels */
520
  int num = 0;
521
522
  WALK_LIST(c, p->p.channels)
523
  {
524
    const struct bgp_af_caps *loc = bgp_find_af_caps(local, c->afi);
525
    const struct bgp_af_caps *rem = bgp_find_af_caps(peer,  c->afi);
526
527
    /* Ignore AFIs that were not announced in multiprotocol capability */
528
    if (!loc || !loc->ready)
529
      loc = &dummy_af_caps;
530
531
    if (!rem || !rem->ready)
532
      rem = &dummy_af_caps;
533
534
    int active = loc->ready && rem->ready;
535
    c->c.disabled = !active;
536
    c->c.reloadable = p->route_refresh;
537
538
    c->index = active ? num++ : 0;
539
540
    c->feed_state = BFS_NONE;
541
    c->load_state = BFS_NONE;
542
543
    /* Channels where peer may do GR */
544
    c->gr_ready = active && local->gr_aware && rem->gr_able;
545
    p->gr_ready = p->gr_ready || c->gr_ready;
546 0c791f87 Ondrej Zajicek
547 d15b0b0a Ondrej Zajicek (work)
    /* Channels not able to recover gracefully */
548
    if (p->p.gr_recovery && (!active || !peer_gr_ready))
549
      channel_graceful_restart_unlock(&c->c);
550 9aed29e6 Ondrej Zajicek
551 d15b0b0a Ondrej Zajicek (work)
    /* Channels waiting for local convergence */
552
    if (p->p.gr_recovery && loc->gr_able && peer_gr_ready)
553
      c->c.gr_wait = 1;
554
555
    /* Channels where peer is not able to recover gracefully */
556
    if (c->gr_active && ! (c->gr_ready && (rem->gr_af_flags & BGP_GRF_FORWARDING)))
557
      bgp_graceful_restart_done(c);
558
559
    /* GR capability implies that neighbor will send End-of-RIB */
560
    if (peer->gr_aware)
561
      c->load_state = BFS_LOADING;
562
563 d8022d26 Ondrej Zajicek (work)
    c->ext_next_hop = c->cf->ext_next_hop && (bgp_channel_is_ipv6(c) || rem->ext_next_hop);
564 d15b0b0a Ondrej Zajicek (work)
    c->add_path_rx = (loc->add_path & BGP_ADD_PATH_RX) && (rem->add_path & BGP_ADD_PATH_TX);
565
    c->add_path_tx = (loc->add_path & BGP_ADD_PATH_TX) && (rem->add_path & BGP_ADD_PATH_RX);
566
567 f8aad5d5 Ondrej Zajicek (work)
    /* Update RA mode */
568 d15b0b0a Ondrej Zajicek (work)
    if (c->add_path_tx)
569
      c->c.ra_mode = RA_ANY;
570 f8aad5d5 Ondrej Zajicek (work)
    else if (c->cf->secondary)
571
      c->c.ra_mode = RA_ACCEPTED;
572
    else
573
      c->c.ra_mode = RA_OPTIMAL;
574 d15b0b0a Ondrej Zajicek (work)
  }
575
576
  p->afi_map = mb_alloc(p->p.pool, num * sizeof(u32));
577
  p->channel_map = mb_alloc(p->p.pool, num * sizeof(void *));
578
  p->channel_count = num;
579
580
  WALK_LIST(c, p->p.channels)
581
  {
582
    if (c->c.disabled)
583
      continue;
584
585
    p->afi_map[c->index] = c->afi;
586
    p->channel_map[c->index] = c;
587
  }
588
589
  /* proto_notify_state() will likely call bgp_feed_begin(), setting c->feed_state */
590 9aed29e6 Ondrej Zajicek
591 cf31112f Ondrej Zajicek
  bgp_conn_set_state(conn, BS_ESTABLISHED);
592 11b32d91 Ondrej Zajicek
  proto_notify_state(&p->p, PS_UP);
593
}
594
595
static void
596
bgp_conn_leave_established_state(struct bgp_proto *p)
597
{
598
  BGP_TRACE(D_EVENTS, "BGP session closed");
599
  p->conn = NULL;
600
601 c259669f Ondrej Zajicek (work)
  // XXXX free these tables to avoid memory leak during graceful restart
602
  // bgp_free_prefix_table(p);
603
  // bgp_free_bucket_table(p);
604 ed1a908e Ondrej Zajicek (work)
605 11b32d91 Ondrej Zajicek
  if (p->p.proto_state == PS_UP)
606 b99d3786 Ondrej Zajicek
    bgp_stop(p, 0);
607 11b32d91 Ondrej Zajicek
}
608
609
void
610
bgp_conn_enter_close_state(struct bgp_conn *conn)
611
{
612
  struct bgp_proto *p = conn->bgp;
613
  int os = conn->state;
614
615 cf31112f Ondrej Zajicek
  bgp_conn_set_state(conn, BS_CLOSE);
616 11b32d91 Ondrej Zajicek
  tm_stop(conn->keepalive_timer);
617
  conn->sk->rx_hook = NULL;
618
619 48b15ef1 Ondrej Zajicek
  /* Timeout for CLOSE state, if we cannot send notification soon then we just hangup */
620
  bgp_start_timer(conn->hold_timer, 10);
621
622 11b32d91 Ondrej Zajicek
  if (os == BS_ESTABLISHED)
623
    bgp_conn_leave_established_state(p);
624
}
625
626
void
627
bgp_conn_enter_idle_state(struct bgp_conn *conn)
628
{
629
  struct bgp_proto *p = conn->bgp;
630
  int os = conn->state;
631
632
  bgp_close_conn(conn);
633 cf31112f Ondrej Zajicek
  bgp_conn_set_state(conn, BS_IDLE);
634 11b32d91 Ondrej Zajicek
  ev_schedule(p->event);
635
636
  if (os == BS_ESTABLISHED)
637
    bgp_conn_leave_established_state(p);
638
}
639
640 6eda3f13 Ondrej Zajicek
/**
641
 * bgp_handle_graceful_restart - handle detected BGP graceful restart
642
 * @p: BGP instance
643
 *
644
 * This function is called when a BGP graceful restart of the neighbor is
645
 * detected (when the TCP connection fails or when a new TCP connection
646
 * appears). The function activates processing of the restart - starts routing
647
 * table refresh cycle and activates BGP restart timer. The protocol state goes
648
 * back to %PS_START, but changing BGP state back to %BS_IDLE is left for the
649
 * caller.
650
 */
651 0c791f87 Ondrej Zajicek
void
652
bgp_handle_graceful_restart(struct bgp_proto *p)
653
{
654
  ASSERT(p->conn && (p->conn->state == BS_ESTABLISHED) && p->gr_ready);
655
656
  BGP_TRACE(D_EVENTS, "Neighbor graceful restart detected%s",
657 d15b0b0a Ondrej Zajicek (work)
            p->gr_active_num ? " - already pending" : "");
658
659
  p->gr_active_num = 0;
660 0c791f87 Ondrej Zajicek
661 d15b0b0a Ondrej Zajicek (work)
  struct bgp_channel *c;
662
  WALK_LIST(c, p->p.channels)
663
  {
664
    if (c->gr_ready)
665
    {
666
      if (c->gr_active)
667
        rt_refresh_end(c->c.table, &c->c);
668 0c791f87 Ondrej Zajicek
669 d15b0b0a Ondrej Zajicek (work)
      c->gr_active = 1;
670
      p->gr_active_num++;
671
      rt_refresh_begin(c->c.table, &c->c);
672
    }
673
    else
674
    {
675
      /* Just flush the routes */
676
      rt_refresh_begin(c->c.table, &c->c);
677
      rt_refresh_end(c->c.table, &c->c);
678
    }
679
  }
680
681
  proto_notify_state(&p->p, PS_START);
682
  bgp_start_timer(p->gr_timer, p->conn->local_caps->gr_time);
683 0c791f87 Ondrej Zajicek
}
684
685 6eda3f13 Ondrej Zajicek
/**
686
 * bgp_graceful_restart_done - finish active BGP graceful restart
687 d15b0b0a Ondrej Zajicek (work)
 * @c: BGP channel
688 6eda3f13 Ondrej Zajicek
 *
689
 * This function is called when the active BGP graceful restart of the neighbor
690 d15b0b0a Ondrej Zajicek (work)
 * should be finished for channel @c - either successfully (the neighbor sends
691
 * all paths and reports end-of-RIB for given AFI/SAFI on the new session) or
692
 * unsuccessfully (the neighbor does not support BGP graceful restart on the new
693
 * session). The function ends the routing table refresh cycle.
694 6eda3f13 Ondrej Zajicek
 */
695 0c791f87 Ondrej Zajicek
void
696 d15b0b0a Ondrej Zajicek (work)
bgp_graceful_restart_done(struct bgp_channel *c)
697 0c791f87 Ondrej Zajicek
{
698 d15b0b0a Ondrej Zajicek (work)
  struct bgp_proto *p = (void *) c->c.proto;
699
700
  ASSERT(c->gr_active);
701
  c->gr_active = 0;
702
  p->gr_active_num--;
703
704
  if (!p->gr_active_num)
705
    BGP_TRACE(D_EVENTS, "Neighbor graceful restart done");
706
707
  rt_refresh_end(c->c.table, &c->c);
708 0c791f87 Ondrej Zajicek
}
709
710 6eda3f13 Ondrej Zajicek
/**
711
 * bgp_graceful_restart_timeout - timeout of graceful restart 'restart timer'
712
 * @t: timer
713
 *
714
 * This function is a timeout hook for @gr_timer, implementing BGP restart time
715
 * limit for reestablisment of the BGP session after the graceful restart. When
716
 * fired, we just proceed with the usual protocol restart.
717
 */
718
719 0c791f87 Ondrej Zajicek
static void
720
bgp_graceful_restart_timeout(timer *t)
721
{
722
  struct bgp_proto *p = t->data;
723
724
  BGP_TRACE(D_EVENTS, "Neighbor graceful restart timeout");
725
  bgp_stop(p, 0);
726
}
727
728 9aed29e6 Ondrej Zajicek
729
/**
730
 * bgp_refresh_begin - start incoming enhanced route refresh sequence
731 d15b0b0a Ondrej Zajicek (work)
 * @c: BGP channel
732 9aed29e6 Ondrej Zajicek
 *
733
 * This function is called when an incoming enhanced route refresh sequence is
734
 * started by the neighbor, demarcated by the BoRR packet. The function updates
735
 * the load state and starts the routing table refresh cycle. Note that graceful
736
 * restart also uses routing table refresh cycle, but RFC 7313 and load states
737
 * ensure that these two sequences do not overlap.
738
 */
739
void
740 d15b0b0a Ondrej Zajicek (work)
bgp_refresh_begin(struct bgp_channel *c)
741 9aed29e6 Ondrej Zajicek
{
742 d15b0b0a Ondrej Zajicek (work)
  struct bgp_proto *p = (void *) c->c.proto;
743
744
  if (c->load_state == BFS_LOADING)
745
  { log(L_WARN "%s: BEGIN-OF-RR received before END-OF-RIB, ignoring", p->p.name); return; }
746 9aed29e6 Ondrej Zajicek
747 d15b0b0a Ondrej Zajicek (work)
  c->load_state = BFS_REFRESHING;
748
  rt_refresh_begin(c->c.table, &c->c);
749 9aed29e6 Ondrej Zajicek
}
750
751
/**
752
 * bgp_refresh_end - finish incoming enhanced route refresh sequence
753 d15b0b0a Ondrej Zajicek (work)
 * @c: BGP channel
754 9aed29e6 Ondrej Zajicek
 *
755
 * This function is called when an incoming enhanced route refresh sequence is
756
 * finished by the neighbor, demarcated by the EoRR packet. The function updates
757
 * the load state and ends the routing table refresh cycle. Routes not received
758
 * during the sequence are removed by the nest.
759
 */
760
void
761 d15b0b0a Ondrej Zajicek (work)
bgp_refresh_end(struct bgp_channel *c)
762 9aed29e6 Ondrej Zajicek
{
763 d15b0b0a Ondrej Zajicek (work)
  struct bgp_proto *p = (void *) c->c.proto;
764 9aed29e6 Ondrej Zajicek
765 d15b0b0a Ondrej Zajicek (work)
  if (c->load_state != BFS_REFRESHING)
766
  { log(L_WARN "%s: END-OF-RR received without prior BEGIN-OF-RR, ignoring", p->p.name); return; }
767
768
  c->load_state = BFS_NONE;
769
  rt_refresh_end(c->c.table, &c->c);
770 9aed29e6 Ondrej Zajicek
}
771
772
773 11b32d91 Ondrej Zajicek
static void
774 c01e3741 Martin Mares
bgp_send_open(struct bgp_conn *conn)
775
{
776
  DBG("BGP: Sending open\n");
777
  conn->sk->rx_hook = bgp_rx;
778 b552ecc4 Martin Mares
  conn->sk->tx_hook = bgp_tx;
779 d15b0b0a Ondrej Zajicek (work)
  tm_stop(conn->connect_timer);
780
  bgp_schedule_packet(conn, NULL, PKT_OPEN);
781 cf31112f Ondrej Zajicek
  bgp_conn_set_state(conn, BS_OPENSENT);
782 3fdbafb6 Martin Mares
  bgp_start_timer(conn->hold_timer, conn->bgp->cf->initial_hold_time);
783 c01e3741 Martin Mares
}
784
785 3fdbafb6 Martin Mares
static void
786
bgp_connected(sock *sk)
787 c01e3741 Martin Mares
{
788
  struct bgp_conn *conn = sk->data;
789 85368cd4 Martin Mares
  struct bgp_proto *p = conn->bgp;
790 c01e3741 Martin Mares
791 85368cd4 Martin Mares
  BGP_TRACE(D_EVENTS, "Connected");
792 c01e3741 Martin Mares
  bgp_send_open(conn);
793
}
794
795
static void
796
bgp_connect_timeout(timer *t)
797
{
798 3fdbafb6 Martin Mares
  struct bgp_conn *conn = t->data;
799 85368cd4 Martin Mares
  struct bgp_proto *p = conn->bgp;
800 c01e3741 Martin Mares
801 85368cd4 Martin Mares
  DBG("BGP: connect_timeout\n");
802 11b32d91 Ondrej Zajicek
  if (p->p.proto_state == PS_START)
803 d15b0b0a Ondrej Zajicek (work)
  {
804
    bgp_close_conn(conn);
805
    bgp_connect(p);
806
  }
807 11b32d91 Ondrej Zajicek
  else
808
    bgp_conn_enter_idle_state(conn);
809 c01e3741 Martin Mares
}
810
811
static void
812 3fdbafb6 Martin Mares
bgp_sock_err(sock *sk, int err)
813 c01e3741 Martin Mares
{
814
  struct bgp_conn *conn = sk->data;
815 85368cd4 Martin Mares
  struct bgp_proto *p = conn->bgp;
816 c01e3741 Martin Mares
817 47597724 Ondrej Zajicek
  /*
818
   * This error hook may be called either asynchronously from main
819
   * loop, or synchronously from sk_send().  But sk_send() is called
820
   * only from bgp_tx() and bgp_kick_tx(), which are both called
821
   * asynchronously from main loop. Moreover, they end if err hook is
822
   * called. Therefore, we could suppose that it is always called
823
   * asynchronously.
824
   */
825
826 11b32d91 Ondrej Zajicek
  bgp_store_error(p, conn, BE_SOCKET, err);
827
828 53943a00 Martin Mares
  if (err)
829
    BGP_TRACE(D_EVENTS, "Connection lost (%M)", err);
830
  else
831
    BGP_TRACE(D_EVENTS, "Connection closed");
832 11b32d91 Ondrej Zajicek
833 0c791f87 Ondrej Zajicek
  if ((conn->state == BS_ESTABLISHED) && p->gr_ready)
834
    bgp_handle_graceful_restart(p);
835
836 11b32d91 Ondrej Zajicek
  bgp_conn_enter_idle_state(conn);
837 c01e3741 Martin Mares
}
838
839
static void
840 3fdbafb6 Martin Mares
bgp_hold_timeout(timer *t)
841
{
842
  struct bgp_conn *conn = t->data;
843 48b15ef1 Ondrej Zajicek
  struct bgp_proto *p = conn->bgp;
844 3fdbafb6 Martin Mares
845 ea89da38 Ondrej Zajicek
  DBG("BGP: Hold timeout\n");
846
847 48b15ef1 Ondrej Zajicek
  /* We are already closing the connection - just do hangup */
848
  if (conn->state == BS_CLOSE)
849
  {
850
    BGP_TRACE(D_EVENTS, "Connection stalled");
851
    bgp_conn_enter_idle_state(conn);
852
    return;
853
  }
854
855 ea89da38 Ondrej Zajicek
  /* If there is something in input queue, we are probably congested
856
     and perhaps just not processed BGP packets in time. */
857
858
  if (sk_rx_ready(conn->sk) > 0)
859
    bgp_start_timer(conn->hold_timer, 10);
860
  else
861
    bgp_error(conn, 4, 0, NULL, 0);
862 3fdbafb6 Martin Mares
}
863
864
static void
865
bgp_keepalive_timeout(timer *t)
866
{
867
  struct bgp_conn *conn = t->data;
868
869
  DBG("BGP: Keepalive timer\n");
870 d15b0b0a Ondrej Zajicek (work)
  bgp_schedule_packet(conn, NULL, PKT_KEEPALIVE);
871 bd22d7f4 Ondrej Zajicek (work)
872
  /* Kick TX a bit faster */
873
  if (ev_active(conn->tx_ev))
874
    ev_run(conn->tx_ev);
875 3fdbafb6 Martin Mares
}
876
877
static void
878 6fd766c1 Martin Mares
bgp_setup_conn(struct bgp_proto *p, struct bgp_conn *conn)
879 c01e3741 Martin Mares
{
880 6fd766c1 Martin Mares
  conn->sk = NULL;
881 c01e3741 Martin Mares
  conn->bgp = p;
882 d15b0b0a Ondrej Zajicek (work)
883 72a6ef11 Martin Mares
  conn->packets_to_send = 0;
884 d15b0b0a Ondrej Zajicek (work)
  conn->channels_to_send = 0;
885
  conn->last_channel = 0;
886
  conn->last_channel_count = 0;
887
888
  conn->connect_timer        = tm_new_set(p->p.pool, bgp_connect_timeout,        conn, 0, 0);
889
  conn->hold_timer         = tm_new_set(p->p.pool, bgp_hold_timeout,        conn, 0, 0);
890
  conn->keepalive_timer        = tm_new_set(p->p.pool, bgp_keepalive_timeout,        conn, 0, 0);
891 c01e3741 Martin Mares
892 11b32d91 Ondrej Zajicek
  conn->tx_ev = ev_new(p->p.pool);
893
  conn->tx_ev->hook = bgp_kick_tx;
894
  conn->tx_ev->data = conn;
895 c01e3741 Martin Mares
}
896
897
static void
898 e81b440f Ondrej Zajicek
bgp_setup_sk(struct bgp_conn *conn, sock *s)
899 6fd766c1 Martin Mares
{
900
  s->data = conn;
901
  s->err_hook = bgp_sock_err;
902 9e7b3ebd Ondrej Zajicek (work)
  s->fast_rx = 1;
903 6fd766c1 Martin Mares
  conn->sk = s;
904
}
905
906 11b32d91 Ondrej Zajicek
static void
907 dd91e467 Ondrej Zajicek
bgp_active(struct bgp_proto *p)
908 11b32d91 Ondrej Zajicek
{
909 6cf72d7a Ondrej Zajicek
  int delay = MAX(1, p->cf->connect_delay_time);
910 11b32d91 Ondrej Zajicek
  struct bgp_conn *conn = &p->outgoing_conn;
911
912
  BGP_TRACE(D_EVENTS, "Connect delayed by %d seconds", delay);
913
  bgp_setup_conn(p, conn);
914 cf31112f Ondrej Zajicek
  bgp_conn_set_state(conn, BS_ACTIVE);
915 d15b0b0a Ondrej Zajicek (work)
  bgp_start_timer(conn->connect_timer, delay);
916 11b32d91 Ondrej Zajicek
}
917
918 54e55169 Martin Mares
/**
919
 * bgp_connect - initiate an outgoing connection
920
 * @p: BGP instance
921
 *
922
 * The bgp_connect() function creates a new &bgp_conn and initiates
923
 * a TCP connection to the peer. The rest of connection setup is governed
924
 * by the BGP state machine as described in the standard.
925
 */
926 6fd766c1 Martin Mares
static void
927 c01e3741 Martin Mares
bgp_connect(struct bgp_proto *p)        /* Enter Connect state and start establishing connection */
928
{
929 b552ecc4 Martin Mares
  struct bgp_conn *conn = &p->outgoing_conn;
930 b1b19433 Ondrej Zajicek
  int hops = p->cf->multihop ? : 1;
931 c01e3741 Martin Mares
932
  DBG("BGP: Connecting\n");
933 d15b0b0a Ondrej Zajicek (work)
  sock *s = sk_new(p->p.pool);
934 c01e3741 Martin Mares
  s->type = SK_TCP_ACTIVE;
935 ad440a57 Ondrej Zajicek
  s->saddr = p->source_addr;
936 c01e3741 Martin Mares
  s->daddr = p->cf->remote_ip;
937 dcde7ae5 Ondrej Zajicek
  s->dport = p->cf->remote_port;
938 53ffbff3 Ondrej Zajicek
  s->iface = p->neigh ? p->neigh->iface : NULL;
939 b1b19433 Ondrej Zajicek
  s->ttl = p->cf->ttl_security ? 255 : hops;
940 06e0d1b6 Ondrej Zajicek
  s->rbsize = p->cf->enable_extended_messages ? BGP_RX_BUFFER_EXT_SIZE : BGP_RX_BUFFER_SIZE;
941
  s->tbsize = p->cf->enable_extended_messages ? BGP_TX_BUFFER_EXT_SIZE : BGP_TX_BUFFER_SIZE;
942 a39b165e Ondrej Zajicek
  s->tos = IP_PREC_INTERNET_CONTROL;
943
  s->password = p->cf->password;
944
  s->tx_hook = bgp_connected;
945 53ffbff3 Ondrej Zajicek
  BGP_TRACE(D_EVENTS, "Connecting to %I%J from local address %I%J", s->daddr, p->cf->iface,
946 88a183c6 Ondrej Zajicek
            s->saddr, ipa_is_link_local(s->saddr) ? s->iface : NULL);
947 6fd766c1 Martin Mares
  bgp_setup_conn(p, conn);
948 e81b440f Ondrej Zajicek
  bgp_setup_sk(conn, s);
949 cf31112f Ondrej Zajicek
  bgp_conn_set_state(conn, BS_CONNECT);
950 b1b19433 Ondrej Zajicek
951
  if (sk_open(s) < 0)
952 05476c4d Ondrej Zajicek
    goto err;
953 b1b19433 Ondrej Zajicek
954
  /* Set minimal receive TTL if needed */
955
  if (p->cf->ttl_security)
956
    if (sk_set_min_ttl(s, 256 - hops) < 0)
957 05476c4d Ondrej Zajicek
      goto err;
958 b1b19433 Ondrej Zajicek
959 c01e3741 Martin Mares
  DBG("BGP: Waiting for connect success\n");
960 d15b0b0a Ondrej Zajicek (work)
  bgp_start_timer(conn->connect_timer, p->cf->connect_retry_time);
961 05476c4d Ondrej Zajicek
  return;
962
963 d15b0b0a Ondrej Zajicek (work)
err:
964 05476c4d Ondrej Zajicek
  sk_log_error(s, p->p.name);
965
  bgp_sock_err(s, 0);
966
  return;
967 c01e3741 Martin Mares
}
968
969 54e55169 Martin Mares
/**
970 374917ad Ondrej Zajicek
 * bgp_find_proto - find existing proto for incoming connection
971
 * @sk: TCP socket
972
 *
973
 */
974
static struct bgp_proto *
975
bgp_find_proto(sock *sk)
976
{
977 d15b0b0a Ondrej Zajicek (work)
  struct bgp_proto *p;
978 374917ad Ondrej Zajicek
979 d15b0b0a Ondrej Zajicek (work)
  WALK_LIST(p, proto_list)
980
    if ((p->p.proto == &proto_bgp) &&
981
        ipa_equal(p->cf->remote_ip, sk->daddr) &&
982 e919601a Ondrej Zajicek (work)
        (!p->cf->iface  || (p->cf->iface == sk->iface)) &&
983 d15b0b0a Ondrej Zajicek (work)
        (ipa_zero(p->cf->local_ip) || ipa_equal(p->cf->local_ip, sk->saddr)) &&
984
        (p->cf->local_port == sk->sport))
985
      return p;
986 374917ad Ondrej Zajicek
987
  return NULL;
988
}
989
990
/**
991 54e55169 Martin Mares
 * bgp_incoming_connection - handle an incoming connection
992
 * @sk: TCP socket
993
 * @dummy: unused
994
 *
995
 * This function serves as a socket hook for accepting of new BGP
996
 * connections. It searches a BGP instance corresponding to the peer
997
 * which has connected and if such an instance exists, it creates a
998
 * &bgp_conn structure, attaches it to the instance and either sends
999
 * an Open message or (if there already is an active connection) it
1000
 * closes the new connection by sending a Notification message.
1001
 */
1002 48e842cc Martin Mares
static int
1003 3e236955 Jan Moskyto Matejka
bgp_incoming_connection(sock *sk, uint dummy UNUSED)
1004 c01e3741 Martin Mares
{
1005 374917ad Ondrej Zajicek
  struct bgp_proto *p;
1006
  int acc, hops;
1007 c01e3741 Martin Mares
1008 48e842cc Martin Mares
  DBG("BGP: Incoming connection from %I port %d\n", sk->daddr, sk->dport);
1009 374917ad Ondrej Zajicek
  p = bgp_find_proto(sk);
1010
  if (!p)
1011 d15b0b0a Ondrej Zajicek (work)
  {
1012
    log(L_WARN "BGP: Unexpected connect from unknown address %I%J (port %d)",
1013
        sk->daddr, ipa_is_link_local(sk->daddr) ? sk->iface : NULL, sk->dport);
1014
    rfree(sk);
1015
    return 0;
1016
  }
1017 374917ad Ondrej Zajicek
1018 487c6961 Ondrej Zajicek (work)
  /*
1019
   * BIRD should keep multiple incoming connections in OpenSent state (for
1020
   * details RFC 4271 8.2.1 par 3), but it keeps just one. Duplicate incoming
1021
   * connections are rejected istead. The exception is the case where an
1022
   * incoming connection triggers a graceful restart.
1023
   */
1024
1025 374917ad Ondrej Zajicek
  acc = (p->p.proto_state == PS_START || p->p.proto_state == PS_UP) &&
1026
    (p->start_state >= BSS_CONNECT) && (!p->incoming_conn.sk);
1027 dd91e467 Ondrej Zajicek
1028 374917ad Ondrej Zajicek
  if (p->conn && (p->conn->state == BS_ESTABLISHED) && p->gr_ready)
1029 d15b0b0a Ondrej Zajicek (work)
  {
1030
    bgp_store_error(p, NULL, BE_MISC, BEM_GRACEFUL_RESTART);
1031
    bgp_handle_graceful_restart(p);
1032
    bgp_conn_enter_idle_state(p->conn);
1033
    acc = 1;
1034
1035
    /* There might be separate incoming connection in OpenSent state */
1036
    if (p->incoming_conn.state > BS_ACTIVE)
1037
      bgp_close_conn(&p->incoming_conn);
1038
  }
1039 374917ad Ondrej Zajicek
1040
  BGP_TRACE(D_EVENTS, "Incoming connection from %I%J (port %d) %s",
1041
            sk->daddr, ipa_is_link_local(sk->daddr) ? sk->iface : NULL,
1042
            sk->dport, acc ? "accepted" : "rejected");
1043
1044
  if (!acc)
1045 d15b0b0a Ondrej Zajicek (work)
  {
1046
    rfree(sk);
1047
    return 0;
1048
  }
1049 374917ad Ondrej Zajicek
1050
  hops = p->cf->multihop ? : 1;
1051
1052
  if (sk_set_ttl(sk, p->cf->ttl_security ? 255 : hops) < 0)
1053
    goto err;
1054
1055
  if (p->cf->ttl_security)
1056
    if (sk_set_min_ttl(sk, 256 - hops) < 0)
1057
      goto err;
1058
1059 06e0d1b6 Ondrej Zajicek
  if (p->cf->enable_extended_messages)
1060 d15b0b0a Ondrej Zajicek (work)
  {
1061
    sk->rbsize = BGP_RX_BUFFER_EXT_SIZE;
1062
    sk->tbsize = BGP_TX_BUFFER_EXT_SIZE;
1063
    sk_reallocate(sk);
1064
  }
1065 06e0d1b6 Ondrej Zajicek
1066 374917ad Ondrej Zajicek
  bgp_setup_conn(p, &p->incoming_conn);
1067
  bgp_setup_sk(&p->incoming_conn, sk);
1068
  bgp_send_open(&p->incoming_conn);
1069
  return 0;
1070
1071
err:
1072
  sk_log_error(sk, p->p.name);
1073
  log(L_ERR "%s: Incoming connection aborted", p->p.name);
1074 48e842cc Martin Mares
  rfree(sk);
1075
  return 0;
1076
}
1077
1078 2af25a97 Ondrej Zajicek
static void
1079 e81b440f Ondrej Zajicek
bgp_listen_sock_err(sock *sk UNUSED, int err)
1080 2af25a97 Ondrej Zajicek
{
1081
  if (err == ECONNABORTED)
1082
    log(L_WARN "BGP: Incoming connection aborted");
1083
  else
1084 a34b0934 Ondrej Zajicek
    log(L_ERR "BGP: Error on listening socket: %M", err);
1085 2af25a97 Ondrej Zajicek
}
1086
1087 acfce55c Martin Mares
static void
1088
bgp_start_neighbor(struct bgp_proto *p)
1089
{
1090 9be9a264 Ondrej Zajicek
  /* Called only for single-hop BGP sessions */
1091
1092
  if (ipa_zero(p->source_addr))
1093 523f020b Ondrej Zajicek
    p->source_addr = p->neigh->ifa->ip;
1094 ad440a57 Ondrej Zajicek
1095 d15b0b0a Ondrej Zajicek (work)
  if (ipa_is_link_local(p->source_addr))
1096
    p->link_addr = p->source_addr;
1097 153f02da Ondrej Zajicek (work)
  else if (p->neigh->iface->llv6)
1098
    p->link_addr = p->neigh->iface->llv6->ip;
1099 11b32d91 Ondrej Zajicek
1100 6fd766c1 Martin Mares
  bgp_initiate(p);
1101 48e842cc Martin Mares
}
1102
1103
static void
1104
bgp_neigh_notify(neighbor *n)
1105
{
1106
  struct bgp_proto *p = (struct bgp_proto *) n->proto;
1107 523f020b Ondrej Zajicek
  int ps = p->p.proto_state;
1108
1109
  if (n != p->neigh)
1110
    return;
1111 48e842cc Martin Mares
1112 523f020b Ondrej Zajicek
  if ((ps == PS_DOWN) || (ps == PS_STOP))
1113 b21955e0 Ondrej Zajicek
    return;
1114
1115 523f020b Ondrej Zajicek
  int prepare = (ps == PS_START) && (p->start_state == BSS_PREPARE);
1116
1117
  if (n->scope <= 0)
1118 d15b0b0a Ondrej Zajicek (work)
  {
1119
    if (!prepare)
1120 48e842cc Martin Mares
    {
1121 d15b0b0a Ondrej Zajicek (work)
      BGP_TRACE(D_EVENTS, "Neighbor lost");
1122
      bgp_store_error(p, NULL, BE_MISC, BEM_NEIGHBOR_LOST);
1123
      /* Perhaps also run bgp_update_startup_delay(p)? */
1124
      bgp_stop(p, 0);
1125 523f020b Ondrej Zajicek
    }
1126 d15b0b0a Ondrej Zajicek (work)
  }
1127 523f020b Ondrej Zajicek
  else if (p->cf->check_link && !(n->iface->flags & IF_LINK_UP))
1128 d15b0b0a Ondrej Zajicek (work)
  {
1129
    if (!prepare)
1130 523f020b Ondrej Zajicek
    {
1131 d15b0b0a Ondrej Zajicek (work)
      BGP_TRACE(D_EVENTS, "Link down");
1132
      bgp_store_error(p, NULL, BE_MISC, BEM_LINK_DOWN);
1133
      if (ps == PS_UP)
1134
        bgp_update_startup_delay(p);
1135
      bgp_stop(p, 0);
1136 48e842cc Martin Mares
    }
1137 d15b0b0a Ondrej Zajicek (work)
  }
1138 48e842cc Martin Mares
  else
1139 d15b0b0a Ondrej Zajicek (work)
  {
1140
    if (prepare)
1141 48e842cc Martin Mares
    {
1142 d15b0b0a Ondrej Zajicek (work)
      BGP_TRACE(D_EVENTS, "Neighbor ready");
1143
      bgp_start_neighbor(p);
1144 48e842cc Martin Mares
    }
1145 d15b0b0a Ondrej Zajicek (work)
  }
1146 48e842cc Martin Mares
}
1147
1148 1ec52253 Ondrej Zajicek
static void
1149
bgp_bfd_notify(struct bfd_request *req)
1150
{
1151
  struct bgp_proto *p = req->data;
1152
  int ps = p->p.proto_state;
1153
1154
  if (req->down && ((ps == PS_START) || (ps == PS_UP)))
1155 d15b0b0a Ondrej Zajicek (work)
  {
1156
    BGP_TRACE(D_EVENTS, "BFD session down");
1157
    bgp_store_error(p, NULL, BE_MISC, BEM_BFD_DOWN);
1158
    if (ps == PS_UP)
1159
      bgp_update_startup_delay(p);
1160
    bgp_stop(p, 0);
1161
  }
1162 1ec52253 Ondrej Zajicek
}
1163
1164
static void
1165
bgp_update_bfd(struct bgp_proto *p, int use_bfd)
1166
{
1167
  if (use_bfd && !p->bfd_req)
1168
    p->bfd_req = bfd_request_session(p->p.pool, p->cf->remote_ip, p->source_addr,
1169
                                     p->cf->multihop ? NULL : p->neigh->iface,
1170
                                     bgp_bfd_notify, p);
1171
1172
  if (!use_bfd && p->bfd_req)
1173 d15b0b0a Ondrej Zajicek (work)
  {
1174
    rfree(p->bfd_req);
1175
    p->bfd_req = NULL;
1176
  }
1177 1ec52253 Ondrej Zajicek
}
1178
1179 d15b0b0a Ondrej Zajicek (work)
static void
1180
bgp_reload_routes(struct channel *C)
1181 bf47fe4b Ondrej Zajicek
{
1182 d15b0b0a Ondrej Zajicek (work)
  struct bgp_proto *p = (void *) C->proto;
1183
  struct bgp_channel *c = (void *) C;
1184 bf47fe4b Ondrej Zajicek
1185 d15b0b0a Ondrej Zajicek (work)
  ASSERT(p->conn && p->route_refresh);
1186
1187
  bgp_schedule_packet(p->conn, c, PKT_ROUTE_REFRESH);
1188 bf47fe4b Ondrej Zajicek
}
1189
1190 48e842cc Martin Mares
static void
1191 d15b0b0a Ondrej Zajicek (work)
bgp_feed_begin(struct channel *C, int initial)
1192 0c791f87 Ondrej Zajicek
{
1193 d15b0b0a Ondrej Zajicek (work)
  struct bgp_proto *p = (void *) C->proto;
1194
  struct bgp_channel *c = (void *) C;
1195 9aed29e6 Ondrej Zajicek
1196
  /* This should not happen */
1197
  if (!p->conn)
1198 0c791f87 Ondrej Zajicek
    return;
1199
1200 9aed29e6 Ondrej Zajicek
  if (initial && p->cf->gr_mode)
1201 d15b0b0a Ondrej Zajicek (work)
    c->feed_state = BFS_LOADING;
1202 9aed29e6 Ondrej Zajicek
1203
  /* It is refeed and both sides support enhanced route refresh */
1204 d15b0b0a Ondrej Zajicek (work)
  if (!initial && p->enhanced_refresh)
1205
  {
1206
    /* BoRR must not be sent before End-of-RIB */
1207
    if (c->feed_state == BFS_LOADING || c->feed_state == BFS_LOADED)
1208
      return;
1209 9aed29e6 Ondrej Zajicek
1210 d15b0b0a Ondrej Zajicek (work)
    c->feed_state = BFS_REFRESHING;
1211
    bgp_schedule_packet(p->conn, c, PKT_BEGIN_REFRESH);
1212
  }
1213 9aed29e6 Ondrej Zajicek
}
1214
1215
static void
1216 d15b0b0a Ondrej Zajicek (work)
bgp_feed_end(struct channel *C)
1217 9aed29e6 Ondrej Zajicek
{
1218 d15b0b0a Ondrej Zajicek (work)
  struct bgp_proto *p = (void *) C->proto;
1219
  struct bgp_channel *c = (void *) C;
1220 9aed29e6 Ondrej Zajicek
1221
  /* This should not happen */
1222
  if (!p->conn)
1223
    return;
1224
1225
  /* Non-demarcated feed ended, nothing to do */
1226 d15b0b0a Ondrej Zajicek (work)
  if (c->feed_state == BFS_NONE)
1227 9aed29e6 Ondrej Zajicek
    return;
1228
1229
  /* Schedule End-of-RIB packet */
1230 d15b0b0a Ondrej Zajicek (work)
  if (c->feed_state == BFS_LOADING)
1231
    c->feed_state = BFS_LOADED;
1232 9aed29e6 Ondrej Zajicek
1233
  /* Schedule EoRR packet */
1234 d15b0b0a Ondrej Zajicek (work)
  if (c->feed_state == BFS_REFRESHING)
1235
    c->feed_state = BFS_REFRESHED;
1236 9aed29e6 Ondrej Zajicek
1237
  /* Kick TX hook */
1238 d15b0b0a Ondrej Zajicek (work)
  bgp_schedule_packet(p->conn, c, PKT_UPDATE);
1239 0c791f87 Ondrej Zajicek
}
1240
1241 9aed29e6 Ondrej Zajicek
1242 0c791f87 Ondrej Zajicek
static void
1243 48e842cc Martin Mares
bgp_start_locked(struct object_lock *lock)
1244
{
1245
  struct bgp_proto *p = lock->data;
1246
  struct bgp_config *cf = p->cf;
1247
1248 11b32d91 Ondrej Zajicek
  if (p->p.proto_state != PS_START)
1249 d15b0b0a Ondrej Zajicek (work)
  {
1250
    DBG("BGP: Got lock in different state %d\n", p->p.proto_state);
1251
    return;
1252
  }
1253 11b32d91 Ondrej Zajicek
1254 48e842cc Martin Mares
  DBG("BGP: Got lock\n");
1255 4847a894 Ondrej Zajicek
1256 9be9a264 Ondrej Zajicek
  if (cf->multihop)
1257 d15b0b0a Ondrej Zajicek (work)
  {
1258
    /* Multi-hop sessions do not use neighbor entries */
1259
    bgp_initiate(p);
1260
    return;
1261
  }
1262 4847a894 Ondrej Zajicek
1263 523f020b Ondrej Zajicek
  neighbor *n = neigh_find2(&p->p, &cf->remote_ip, cf->iface, NEF_STICKY);
1264
  if (!n)
1265 d15b0b0a Ondrej Zajicek (work)
  {
1266
    log(L_ERR "%s: Invalid remote address %I%J", p->p.name, cf->remote_ip, cf->iface);
1267
    /* As we do not start yet, we can just disable protocol */
1268
    p->p.disabled = 1;
1269
    bgp_store_error(p, NULL, BE_MISC, BEM_INVALID_NEXT_HOP);
1270
    proto_notify_state(&p->p, PS_DOWN);
1271
    return;
1272
  }
1273 523f020b Ondrej Zajicek
1274
  p->neigh = n;
1275
1276
  if (n->scope <= 0)
1277 53ffbff3 Ondrej Zajicek
    BGP_TRACE(D_EVENTS, "Waiting for %I%J to become my neighbor", cf->remote_ip, cf->iface);
1278 523f020b Ondrej Zajicek
  else if (p->cf->check_link && !(n->iface->flags & IF_LINK_UP))
1279
    BGP_TRACE(D_EVENTS, "Waiting for link on %s", n->iface->name);
1280
  else
1281
    bgp_start_neighbor(p);
1282 c01e3741 Martin Mares
}
1283
1284 2638249d Martin Mares
static int
1285
bgp_start(struct proto *P)
1286
{
1287 c01e3741 Martin Mares
  struct bgp_proto *p = (struct bgp_proto *) P;
1288
  struct object_lock *lock;
1289
1290 b552ecc4 Martin Mares
  DBG("BGP: Startup.\n");
1291 11b32d91 Ondrej Zajicek
  p->start_state = BSS_PREPARE;
1292 b552ecc4 Martin Mares
  p->outgoing_conn.state = BS_IDLE;
1293
  p->incoming_conn.state = BS_IDLE;
1294 bcbdcbb6 Martin Mares
  p->neigh = NULL;
1295 1ec52253 Ondrej Zajicek
  p->bfd_req = NULL;
1296 0c791f87 Ondrej Zajicek
  p->gr_ready = 0;
1297 d15b0b0a Ondrej Zajicek (work)
  p->gr_active_num = 0;
1298 cfe34a31 Ondrej Zajicek
1299 11b32d91 Ondrej Zajicek
  p->event = ev_new(p->p.pool);
1300
  p->event->hook = bgp_decision;
1301
  p->event->data = p;
1302 79681f4a Martin Mares
1303 dd91e467 Ondrej Zajicek
  p->startup_timer = tm_new(p->p.pool);
1304
  p->startup_timer->hook = bgp_startup_timeout;
1305
  p->startup_timer->data = p;
1306
1307 0c791f87 Ondrej Zajicek
  p->gr_timer = tm_new(p->p.pool);
1308
  p->gr_timer->hook = bgp_graceful_restart_timeout;
1309
  p->gr_timer->data = p;
1310
1311 4ef09506 Ondrej Zajicek
  p->local_id = proto_get_router_id(P->cf);
1312
  if (p->rr_client)
1313
    p->rr_cluster_id = p->cf->rr_cluster_id ? p->cf->rr_cluster_id : p->local_id;
1314
1315 9be9a264 Ondrej Zajicek
  p->remote_id = 0;
1316 d15b0b0a Ondrej Zajicek (work)
  p->source_addr = p->cf->local_ip;
1317 ef57b70f Ondrej Zajicek (work)
  p->link_addr = IPA_NONE;
1318 9be9a264 Ondrej Zajicek
1319 d15b0b0a Ondrej Zajicek (work)
  /* XXXX */
1320 6eda3f13 Ondrej Zajicek
  if (p->p.gr_recovery && p->cf->gr_mode)
1321 d15b0b0a Ondrej Zajicek (work)
  {
1322
    struct bgp_channel *c;
1323
    WALK_LIST(c, p->p.channels)
1324
      channel_graceful_restart_lock(&c->c);
1325
  }
1326 0c791f87 Ondrej Zajicek
1327 c01e3741 Martin Mares
  /*
1328 d15b0b0a Ondrej Zajicek (work)
   * Before attempting to create the connection, we need to lock the port,
1329
   * so that we are the only instance attempting to talk with that neighbor.
1330 c01e3741 Martin Mares
   */
1331
1332
  lock = p->lock = olock_new(P->pool);
1333
  lock->addr = p->cf->remote_ip;
1334 dcde7ae5 Ondrej Zajicek
  lock->port = p->cf->remote_port;
1335 53ffbff3 Ondrej Zajicek
  lock->iface = p->cf->iface;
1336 c01e3741 Martin Mares
  lock->type = OBJLOCK_TCP;
1337
  lock->hook = bgp_start_locked;
1338
  lock->data = p;
1339
  olock_acquire(lock);
1340 d51aa281 Ondrej Zajicek
1341 c01e3741 Martin Mares
  return PS_START;
1342 2638249d Martin Mares
}
1343
1344 d9b77cc2 Ondrej Zajicek
extern int proto_restart;
1345
1346 2638249d Martin Mares
static int
1347
bgp_shutdown(struct proto *P)
1348
{
1349 c01e3741 Martin Mares
  struct bgp_proto *p = (struct bgp_proto *) P;
1350 d15b0b0a Ondrej Zajicek (work)
  uint subcode = 0;
1351 c01e3741 Martin Mares
1352 85368cd4 Martin Mares
  BGP_TRACE(D_EVENTS, "Shutdown requested");
1353 b99d3786 Ondrej Zajicek
1354 ebecb6f6 Ondrej Zajicek
  switch (P->down_code)
1355 d15b0b0a Ondrej Zajicek (work)
  {
1356
  case PDC_CF_REMOVE:
1357
  case PDC_CF_DISABLE:
1358
    subcode = 3; // Errcode 6, 3 - peer de-configured
1359
    break;
1360
1361
  case PDC_CF_RESTART:
1362
    subcode = 6; // Errcode 6, 6 - other configuration change
1363
    break;
1364
1365
  case PDC_CMD_DISABLE:
1366
  case PDC_CMD_SHUTDOWN:
1367
    subcode = 2; // Errcode 6, 2 - administrative shutdown
1368
    break;
1369
1370
  case PDC_CMD_RESTART:
1371
    subcode = 4; // Errcode 6, 4 - administrative reset
1372
    break;
1373
1374
  case PDC_RX_LIMIT_HIT:
1375
  case PDC_IN_LIMIT_HIT:
1376
    subcode = 1; // Errcode 6, 1 - max number of prefixes reached
1377
    /* log message for compatibility */
1378
    log(L_WARN "%s: Route limit exceeded, shutting down", p->p.name);
1379
    goto limit;
1380
1381
  case PDC_OUT_LIMIT_HIT:
1382
    subcode = proto_restart ? 4 : 2; // Administrative reset or shutdown
1383
1384
  limit:
1385
    bgp_store_error(p, NULL, BE_AUTO_DOWN, BEA_ROUTE_LIMIT_EXCEEDED);
1386
    if (proto_restart)
1387
      bgp_update_startup_delay(p);
1388
    else
1389
      p->startup_delay = 0;
1390
    goto done;
1391
  }
1392 b99d3786 Ondrej Zajicek
1393 ebecb6f6 Ondrej Zajicek
  bgp_store_error(p, NULL, BE_MAN_DOWN, 0);
1394 11b32d91 Ondrej Zajicek
  p->startup_delay = 0;
1395 c01e3741 Martin Mares
1396 d15b0b0a Ondrej Zajicek (work)
done:
1397 ebecb6f6 Ondrej Zajicek
  bgp_stop(p, subcode);
1398 11b32d91 Ondrej Zajicek
  return p->p.proto_state;
1399 2638249d Martin Mares
}
1400
1401 48e842cc Martin Mares
static struct proto *
1402 d15b0b0a Ondrej Zajicek (work)
bgp_init(struct proto_config *CF)
1403 48e842cc Martin Mares
{
1404 d15b0b0a Ondrej Zajicek (work)
  struct proto *P = proto_new(CF);
1405 48e842cc Martin Mares
  struct bgp_proto *p = (struct bgp_proto *) P;
1406 d15b0b0a Ondrej Zajicek (work)
  struct bgp_config *cf = (struct bgp_config *) CF;
1407 48e842cc Martin Mares
1408
  P->rt_notify = bgp_rt_notify;
1409
  P->import_control = bgp_import_control;
1410
  P->neigh_notify = bgp_neigh_notify;
1411 bf47fe4b Ondrej Zajicek
  P->reload_routes = bgp_reload_routes;
1412 9aed29e6 Ondrej Zajicek
  P->feed_begin = bgp_feed_begin;
1413
  P->feed_end = bgp_feed_end;
1414 094d2bdb Ondrej Zajicek
  P->rte_better = bgp_rte_better;
1415 8d9eef17 Ondrej Zajicek
  P->rte_mergable = bgp_rte_mergable;
1416 d15b0b0a Ondrej Zajicek (work)
  P->rte_recalculate = cf->deterministic_med ? bgp_rte_recalculate : NULL;
1417
1418
  p->cf = cf;
1419
  p->local_as = cf->local_as;
1420
  p->remote_as = cf->remote_as;
1421
  p->public_as = cf->local_as;
1422
  p->is_internal = (cf->local_as == cf->remote_as);
1423
  p->is_interior = p->is_internal || cf->confederation_member;
1424
  p->rs_client = cf->rs_client;
1425
  p->rr_client = cf->rr_client;
1426
1427
  /* Confederation ID is used for truly external peers */
1428
  if (cf->confederation && !p->is_interior)
1429
    p->public_as = cf->confederation;
1430
1431
  /* Add all channels */
1432
  struct bgp_channel_config *cc;
1433
  WALK_LIST(cc, CF->channels)
1434
    proto_add_channel(P, &cc->c);
1435 9be9a264 Ondrej Zajicek
1436 48e842cc Martin Mares
  return P;
1437
}
1438
1439 d15b0b0a Ondrej Zajicek (work)
static void
1440
bgp_channel_init(struct channel *C, struct channel_config *CF)
1441
{
1442
  struct bgp_channel *c = (void *) C;
1443
  struct bgp_channel_config *cf = (void *) CF;
1444
1445
  c->cf = cf;
1446
  c->afi = cf->afi;
1447 ef57b70f Ondrej Zajicek (work)
  c->desc = cf->desc;
1448
1449
  if (cf->igp_table_ip4)
1450
    c->igp_table_ip4 = cf->igp_table_ip4->table;
1451
1452
  if (cf->igp_table_ip6)
1453
    c->igp_table_ip6 = cf->igp_table_ip6->table;
1454 d15b0b0a Ondrej Zajicek (work)
}
1455
1456
static int
1457
bgp_channel_start(struct channel *C)
1458
{
1459
  struct bgp_proto *p = (void *) C->proto;
1460
  struct bgp_channel *c = (void *) C;
1461
  ip_addr src = p->source_addr;
1462
1463 ef57b70f Ondrej Zajicek (work)
  if (c->igp_table_ip4)
1464
    rt_lock_table(c->igp_table_ip4);
1465
1466
  if (c->igp_table_ip6)
1467
    rt_lock_table(c->igp_table_ip6);
1468 d15b0b0a Ondrej Zajicek (work)
1469
  c->pool = p->p.pool; // XXXX
1470
  bgp_init_bucket_table(c);
1471
  bgp_init_prefix_table(c);
1472
1473
  c->next_hop_addr = c->cf->next_hop_addr;
1474
  c->link_addr = IPA_NONE;
1475
  c->packets_to_send = 0;
1476
1477
  /* Try to use source address as next hop address */
1478
  if (ipa_zero(c->next_hop_addr))
1479
  {
1480 ef57b70f Ondrej Zajicek (work)
    if (bgp_channel_is_ipv4(c) && (ipa_is_ip4(src) || c->ext_next_hop))
1481 d15b0b0a Ondrej Zajicek (work)
      c->next_hop_addr = src;
1482
1483 ef57b70f Ondrej Zajicek (work)
    if (bgp_channel_is_ipv6(c) && (ipa_is_ip6(src) || c->ext_next_hop))
1484 d15b0b0a Ondrej Zajicek (work)
      c->next_hop_addr = src;
1485
  }
1486
1487 ef57b70f Ondrej Zajicek (work)
  /* Exit if no feasible next hop address is found */
1488
  if (ipa_zero(c->next_hop_addr))
1489
  {
1490
    log(L_WARN "%s: Missing next hop address", p->p.name);
1491
    return 0;
1492
  }
1493
1494 d15b0b0a Ondrej Zajicek (work)
  /* Set link-local address for IPv6 single-hop BGP */
1495 ef57b70f Ondrej Zajicek (work)
  if (ipa_is_ip6(c->next_hop_addr) && p->neigh)
1496 d15b0b0a Ondrej Zajicek (work)
  {
1497
    c->link_addr = p->link_addr;
1498
1499
    if (ipa_zero(c->link_addr))
1500
      log(L_WARN "%s: Missing link-local address", p->p.name);
1501
  }
1502
1503 ef57b70f Ondrej Zajicek (work)
  /* Link local address is already in c->link_addr */
1504
  if (ipa_is_link_local(c->next_hop_addr))
1505
    c->next_hop_addr = IPA_NONE;
1506 d15b0b0a Ondrej Zajicek (work)
1507
  return 0; /* XXXX: Currently undefined */
1508
}
1509
1510
static void
1511
bgp_channel_shutdown(struct channel *C)
1512
{
1513
  struct bgp_channel *c = (void *) C;
1514
1515
  /* XXXX: cleanup bucket and prefix tables */
1516
1517
  c->next_hop_addr = IPA_NONE;
1518
  c->link_addr = IPA_NONE;
1519
}
1520
1521
static void
1522
bgp_channel_cleanup(struct channel *C)
1523
{
1524
  struct bgp_channel *c = (void *) C;
1525
1526 ef57b70f Ondrej Zajicek (work)
  if (c->igp_table_ip4)
1527
    rt_unlock_table(c->igp_table_ip4);
1528
1529
  if (c->igp_table_ip6)
1530
    rt_unlock_table(c->igp_table_ip6);
1531
}
1532
1533
static inline struct bgp_channel_config *
1534
bgp_find_channel_config(struct bgp_config *cf, u32 afi)
1535
{
1536
  struct bgp_channel_config *cc;
1537
1538
  WALK_LIST(cc, cf->c.channels)
1539
    if (cc->afi == afi)
1540
      return cc;
1541
1542
  return NULL;
1543 d15b0b0a Ondrej Zajicek (work)
}
1544 a7f23f58 Ondrej Zajicek
1545 ef57b70f Ondrej Zajicek (work)
struct rtable_config *
1546
bgp_default_igp_table(struct bgp_config *cf, struct bgp_channel_config *cc, u32 type)
1547
{
1548
  struct bgp_channel_config *cc2;
1549
  struct rtable_config *tab;
1550
1551
  /* First, try table connected by the channel */
1552
  if (cc->c.table->addr_type == type)
1553
    return cc->c.table;
1554
1555
  /* Find paired channel with the same SAFI but the other AFI */
1556
  u32 afi2 = cc->afi ^ 0x30000;
1557
  cc2 = bgp_find_channel_config(cf, afi2);
1558
1559
  /* Second, try IGP table configured in the paired channel */
1560
  if (cc2 && (tab = (type == NET_IP4) ? cc2->igp_table_ip4 : cc2->igp_table_ip6))
1561
    return tab;
1562
1563
  /* Third, try table connected by the paired channel */
1564
  if (cc2 && (cc2->c.table->addr_type == type))
1565
    return cc2->c.table;
1566
1567
  /* Last, try default table of given type */
1568
  if (tab = cf->c.global->def_tables[type])
1569
    return tab;
1570
1571
  cf_error("Undefined IGP table");
1572
}
1573
1574
1575 a7f23f58 Ondrej Zajicek
void
1576 d15b0b0a Ondrej Zajicek (work)
bgp_postconfig(struct proto_config *CF)
1577 a7f23f58 Ondrej Zajicek
{
1578 d15b0b0a Ondrej Zajicek (work)
  struct bgp_config *cf = (void *) CF;
1579
  int internal = (cf->local_as == cf->remote_as);
1580 a7f23f58 Ondrej Zajicek
1581
  /* Do not check templates at all */
1582 d15b0b0a Ondrej Zajicek (work)
  if (cf->c.class == SYM_TEMPLATE)
1583 a7f23f58 Ondrej Zajicek
    return;
1584
1585 f3e59178 Ondrej Zajicek
1586
  /* EBGP direct by default, IBGP multihop by default */
1587 d15b0b0a Ondrej Zajicek (work)
  if (cf->multihop < 0)
1588
    cf->multihop = internal ? 64 : 0;
1589 f3e59178 Ondrej Zajicek
1590
1591 d15b0b0a Ondrej Zajicek (work)
  if (!cf->local_as)
1592 a7f23f58 Ondrej Zajicek
    cf_error("Local AS number must be set");
1593
1594 d15b0b0a Ondrej Zajicek (work)
  if (ipa_zero(cf->remote_ip))
1595 a7f23f58 Ondrej Zajicek
    cf_error("Neighbor must be configured");
1596
1597 d15b0b0a Ondrej Zajicek (work)
  if (!cf->remote_as)
1598 a1beb8f3 Ondrej Zajicek
    cf_error("Remote AS number must be set");
1599
1600 e919601a Ondrej Zajicek (work)
  if (ipa_is_link_local(cf->remote_ip) && !cf->iface)
1601 33b6c292 Ondrej Zajicek (work)
    cf_error("Link-local neighbor address requires specified interface");
1602 a1beb8f3 Ondrej Zajicek
1603 d15b0b0a Ondrej Zajicek (work)
  if (!(cf->capabilities && cf->enable_as4) && (cf->remote_as > 0xFFFF))
1604 a7f23f58 Ondrej Zajicek
    cf_error("Neighbor AS number out of range (AS4 not available)");
1605
1606 d15b0b0a Ondrej Zajicek (work)
  if (!internal && cf->rr_client)
1607 a7f23f58 Ondrej Zajicek
    cf_error("Only internal neighbor can be RR client");
1608
1609 d15b0b0a Ondrej Zajicek (work)
  if (internal && cf->rs_client)
1610 a7f23f58 Ondrej Zajicek
    cf_error("Only external neighbor can be RS client");
1611
1612 d15b0b0a Ondrej Zajicek (work)
  if (!cf->confederation && cf->confederation_member)
1613
    cf_error("Confederation ID must be set for member sessions");
1614 a7f23f58 Ondrej Zajicek
1615 d15b0b0a Ondrej Zajicek (work)
  if (cf->multihop && (ipa_is_link_local(cf->local_ip) ||
1616
                       ipa_is_link_local(cf->remote_ip)))
1617 53ffbff3 Ondrej Zajicek
    cf_error("Multihop BGP cannot be used with link-local addresses");
1618
1619 e919601a Ondrej Zajicek (work)
  if (cf->multihop && cf->iface)
1620 33b6c292 Ondrej Zajicek (work)
    cf_error("Multihop BGP cannot be bound to interface");
1621
1622 d15b0b0a Ondrej Zajicek (work)
  if (cf->multihop && cf->check_link)
1623 523f020b Ondrej Zajicek
    cf_error("Multihop BGP cannot depend on link state");
1624
1625 d15b0b0a Ondrej Zajicek (work)
  if (cf->multihop && cf->bfd && ipa_zero(cf->local_ip))
1626
    cf_error("Multihop BGP with BFD requires specified local address");
1627
1628
1629
  struct bgp_channel_config *cc;
1630
  WALK_LIST(cc, CF->channels)
1631
  {
1632
    /* Disable after error incompatible with restart limit action */
1633
    if ((cc->c.in_limit.action == PLA_RESTART) && cf->disable_after_error)
1634
      cc->c.in_limit.action = PLA_DISABLE;
1635
1636
    /* Different default based on rs_client */
1637
    if (!cc->missing_lladdr)
1638
      cc->missing_lladdr = cf->rs_client ? MLL_IGNORE : MLL_SELF;
1639
1640
    /* Different default for gw_mode */
1641
    if (!cc->gw_mode)
1642
      cc->gw_mode = cf->multihop ? GW_RECURSIVE : GW_DIRECT;
1643 1ec52253 Ondrej Zajicek
1644 d15b0b0a Ondrej Zajicek (work)
    /* Default based on proto config */
1645
    if (cc->gr_able == 0xff)
1646
      cc->gr_able = (cf->gr_mode == BGP_GR_ABLE);
1647 26822d8f Ondrej Zajicek
1648 6fe11c99 Ondrej Zajicek (work)
    /* Default values of IGP tables */
1649 ef57b70f Ondrej Zajicek (work)
    if ((cc->gw_mode == GW_RECURSIVE) && !cc->desc->no_igp)
1650
    {
1651
      if (!cc->igp_table_ip4 && (bgp_cc_is_ipv4(cc) || cc->ext_next_hop))
1652
        cc->igp_table_ip4 = bgp_default_igp_table(cf, cc, NET_IP4);
1653
1654
      if (!cc->igp_table_ip6 && (bgp_cc_is_ipv6(cc) || cc->ext_next_hop))
1655
        cc->igp_table_ip6 = bgp_default_igp_table(cf, cc, NET_IP6);
1656 6fe11c99 Ondrej Zajicek (work)
1657
      if (cc->igp_table_ip4 && bgp_cc_is_ipv6(cc) && !cc->ext_next_hop)
1658
        cf_error("Mismatched IGP table type");
1659
1660
      if (cc->igp_table_ip6 && bgp_cc_is_ipv4(cc) && !cc->ext_next_hop)
1661
        cf_error("Mismatched IGP table type");
1662 ef57b70f Ondrej Zajicek (work)
    }
1663
1664 d15b0b0a Ondrej Zajicek (work)
    if (cf->multihop && (cc->gw_mode == GW_DIRECT))
1665
      cf_error("Multihop BGP cannot use direct gateway mode");
1666 26822d8f Ondrej Zajicek
1667 d15b0b0a Ondrej Zajicek (work)
    if ((cc->gw_mode == GW_RECURSIVE) && cc->c.table->sorted)
1668
      cf_error("BGP in recursive mode prohibits sorted table");
1669
1670
    if (cf->deterministic_med && cc->c.table->sorted)
1671
      cf_error("BGP with deterministic MED prohibits sorted table");
1672
1673
    if (cc->secondary && !cc->c.table->sorted)
1674
      cf_error("BGP with secondary option requires sorted table");
1675
  }
1676 a7f23f58 Ondrej Zajicek
}
1677
1678
static int
1679 d15b0b0a Ondrej Zajicek (work)
bgp_reconfigure(struct proto *P, struct proto_config *CF)
1680 a7f23f58 Ondrej Zajicek
{
1681 d15b0b0a Ondrej Zajicek (work)
  struct bgp_proto *p = (void *) P;
1682
  struct bgp_config *new = (void *) CF;
1683 a7f23f58 Ondrej Zajicek
  struct bgp_config *old = p->cf;
1684
1685 d15b0b0a Ondrej Zajicek (work)
  if (proto_get_router_id(CF) != p->local_id)
1686 79b4e12e Ondrej Zajicek
    return 0;
1687
1688 a7f23f58 Ondrej Zajicek
  int same = !memcmp(((byte *) old) + sizeof(struct proto_config),
1689
                     ((byte *) new) + sizeof(struct proto_config),
1690
                     // password item is last and must be checked separately
1691
                     OFFSETOF(struct bgp_config, password) - sizeof(struct proto_config))
1692
    && ((!old->password && !new->password)
1693 d15b0b0a Ondrej Zajicek (work)
        || (old->password && new->password && !strcmp(old->password, new->password)));
1694
1695
  /* FIXME: Move channel reconfiguration to generic protocol code ? */
1696
  struct channel *C, *C2;
1697
  struct bgp_channel_config *cc;
1698
1699
  WALK_LIST(C, p->p.channels)
1700
    C->stale = 1;
1701
1702
  WALK_LIST(cc, new->c.channels)
1703
  {
1704
    C = (struct channel *) bgp_find_channel(p, cc->afi);
1705
    same = proto_configure_channel(P, &C, &cc->c) && same;
1706
    C->stale = 0;
1707
  }
1708
1709
  WALK_LIST_DELSAFE(C, C2, p->p.channels)
1710
    if (C->stale)
1711
      same = proto_configure_channel(P, &C, NULL) && same;
1712
1713 a7f23f58 Ondrej Zajicek
1714 1ec52253 Ondrej Zajicek
  if (same && (p->start_state > BSS_PREPARE))
1715
    bgp_update_bfd(p, new->bfd);
1716
1717 a7f23f58 Ondrej Zajicek
  /* We should update our copy of configuration ptr as old configuration will be freed */
1718
  if (same)
1719
    p->cf = new;
1720
1721
  return same;
1722
}
1723
1724 ffb38dfb Ondrej Zajicek (work)
#define IGP_TABLE(cf, sym) ((cf)->igp_table_##sym ? (cf)->igp_table_##sym ->table : NULL )
1725
1726 d15b0b0a Ondrej Zajicek (work)
static int
1727
bgp_channel_reconfigure(struct channel *C, struct channel_config *CC)
1728
{
1729
  struct bgp_channel *c = (void *) C;
1730
  struct bgp_channel_config *new = (void *) CC;
1731
  struct bgp_channel_config *old = c->cf;
1732
1733
  if (memcmp(((byte *) old) + sizeof(struct channel_config),
1734
             ((byte *) new) + sizeof(struct channel_config),
1735 ef57b70f Ondrej Zajicek (work)
             /* Remaining items must be checked separately */
1736
             OFFSETOF(struct bgp_channel_config, rest) - sizeof(struct channel_config)))
1737 d15b0b0a Ondrej Zajicek (work)
    return 0;
1738
1739 ef57b70f Ondrej Zajicek (work)
  /* Check change in IGP tables */
1740 ffb38dfb Ondrej Zajicek (work)
  if ((IGP_TABLE(old, ip4) != IGP_TABLE(new, ip4)) ||
1741
      (IGP_TABLE(old, ip6) != IGP_TABLE(new, ip6)))
1742 d15b0b0a Ondrej Zajicek (work)
    return 0;
1743
1744
  c->cf = new;
1745
  return 1;
1746
}
1747
1748 a7f23f58 Ondrej Zajicek
static void
1749 d15b0b0a Ondrej Zajicek (work)
bgp_copy_config(struct proto_config *dest UNUSED, struct proto_config *src UNUSED)
1750 a7f23f58 Ondrej Zajicek
{
1751
  /* Just a shallow copy */
1752
}
1753
1754
1755 54e55169 Martin Mares
/**
1756
 * bgp_error - report a protocol error
1757
 * @c: connection
1758
 * @code: error code (according to the RFC)
1759 2e9b2421 Martin Mares
 * @subcode: error sub-code
1760 54e55169 Martin Mares
 * @data: data to be passed in the Notification message
1761
 * @len: length of the data
1762
 *
1763
 * bgp_error() sends a notification packet to tell the other side that a protocol
1764 2e9b2421 Martin Mares
 * error has occurred (including the data considered erroneous if possible) and
1765 54e55169 Martin Mares
 * closes the connection.
1766
 */
1767 2638249d Martin Mares
void
1768 d15b0b0a Ondrej Zajicek (work)
bgp_error(struct bgp_conn *c, uint code, uint subcode, byte *data, int len)
1769 3fdbafb6 Martin Mares
{
1770 b99d3786 Ondrej Zajicek
  struct bgp_proto *p = c->bgp;
1771
1772 11b32d91 Ondrej Zajicek
  if (c->state == BS_CLOSE)
1773 3fdbafb6 Martin Mares
    return;
1774 11b32d91 Ondrej Zajicek
1775 d15b0b0a Ondrej Zajicek (work)
  bgp_log_error(p, BE_BGP_TX, "Error", code, subcode, data, ABS(len));
1776 b99d3786 Ondrej Zajicek
  bgp_store_error(p, c, BE_BGP_TX, (code << 16) | subcode);
1777 11b32d91 Ondrej Zajicek
  bgp_conn_enter_close_state(c);
1778
1779 3fdbafb6 Martin Mares
  c->notify_code = code;
1780
  c->notify_subcode = subcode;
1781 efcece2d Martin Mares
  c->notify_data = data;
1782
  c->notify_size = (len > 0) ? len : 0;
1783 d15b0b0a Ondrej Zajicek (work)
  bgp_schedule_packet(c, NULL, PKT_NOTIFICATION);
1784 b99d3786 Ondrej Zajicek
1785
  if (code != 6)
1786 d15b0b0a Ondrej Zajicek (work)
  {
1787
    bgp_update_startup_delay(p);
1788
    bgp_stop(p, 0);
1789
  }
1790 3fdbafb6 Martin Mares
}
1791
1792 11b32d91 Ondrej Zajicek
/**
1793
 * bgp_store_error - store last error for status report
1794
 * @p: BGP instance
1795
 * @c: connection
1796
 * @class: error class (BE_xxx constants)
1797
 * @code: error code (class specific)
1798
 *
1799
 * bgp_store_error() decides whether given error is interesting enough
1800
 * and store that error to last_error variables of @p
1801
 */
1802
void
1803
bgp_store_error(struct bgp_proto *p, struct bgp_conn *c, u8 class, u32 code)
1804
{
1805
  /* During PS_UP, we ignore errors on secondary connection */
1806
  if ((p->p.proto_state == PS_UP) && c && (c != p->conn))
1807
    return;
1808
1809
  /* During PS_STOP, we ignore any errors, as we want to report
1810
   * the error that caused transition to PS_STOP
1811
   */
1812
  if (p->p.proto_state == PS_STOP)
1813
    return;
1814
1815
  p->last_error_class = class;
1816
  p->last_error_code = code;
1817
}
1818
1819
static char *bgp_state_names[] = { "Idle", "Connect", "Active", "OpenSent", "OpenConfirm", "Established", "Close" };
1820 72b28a04 Ondrej Zajicek
static char *bgp_err_classes[] = { "", "Error: ", "Socket: ", "Received: ", "BGP Error: ", "Automatic shutdown: ", ""};
1821 523f020b Ondrej Zajicek
static char *bgp_misc_errors[] = { "", "Neighbor lost", "Invalid next hop", "Kernel MD5 auth failed", "No listening socket", "Link down", "BFD session down", "Graceful restart"};
1822 72b28a04 Ondrej Zajicek
static char *bgp_auto_errors[] = { "", "Route limit exceeded"};
1823 11b32d91 Ondrej Zajicek
1824 b8113a5e Ondrej Zajicek
static const char *
1825
bgp_last_errmsg(struct bgp_proto *p)
1826 973399ae Martin Mares
{
1827 11b32d91 Ondrej Zajicek
  switch (p->last_error_class)
1828 d15b0b0a Ondrej Zajicek (work)
  {
1829
  case BE_MISC:
1830
    return bgp_misc_errors[p->last_error_code];
1831
  case BE_SOCKET:
1832
    return (p->last_error_code == 0) ? "Connection closed" : strerror(p->last_error_code);
1833
  case BE_BGP_RX:
1834
  case BE_BGP_TX:
1835
    return bgp_error_dsc(p->last_error_code >> 16, p->last_error_code & 0xFF);
1836
  case BE_AUTO_DOWN:
1837
    return bgp_auto_errors[p->last_error_code];
1838
  default:
1839
    return "";
1840
  }
1841 b8113a5e Ondrej Zajicek
}
1842
1843
static const char *
1844
bgp_state_dsc(struct bgp_proto *p)
1845
{
1846 51947659 Ondrej Zajicek
  if (p->p.proto_state == PS_DOWN)
1847
    return "Down";
1848 b8113a5e Ondrej Zajicek
1849
  int state = MAX(p->incoming_conn.state, p->outgoing_conn.state);
1850
  if ((state == BS_IDLE) && (p->start_state >= BSS_CONNECT) && p->cf->passive)
1851
    return "Passive";
1852
1853
  return bgp_state_names[state];
1854
}
1855
1856
static void
1857
bgp_get_status(struct proto *P, byte *buf)
1858
{
1859
  struct bgp_proto *p = (struct bgp_proto *) P;
1860
1861
  const char *err1 = bgp_err_classes[p->last_error_class];
1862
  const char *err2 = bgp_last_errmsg(p);
1863 11b32d91 Ondrej Zajicek
1864 f4ab2317 Martin Mares
  if (P->proto_state == PS_DOWN)
1865 11b32d91 Ondrej Zajicek
    bsprintf(buf, "%s%s", err1, err2);
1866 f4ab2317 Martin Mares
  else
1867 b8113a5e Ondrej Zajicek
    bsprintf(buf, "%-14s%s%s", bgp_state_dsc(p), err1, err2);
1868
}
1869
1870
static void
1871 256cc8ee Ondrej Zajicek (work)
bgp_show_afis(int code, char *s, u32 *afis, uint count)
1872
{
1873
  buffer b;
1874
  LOG_BUFFER_INIT(b);
1875
1876
  buffer_puts(&b, s);
1877
1878
  for (u32 *af = afis; af < (afis + count); af++)
1879
  {
1880
    const struct bgp_af_desc *desc = bgp_get_af_desc(*af);
1881
    if (desc)
1882
      buffer_print(&b, " %s", desc->name);
1883
    else
1884
      buffer_print(&b, " <%u/%u>", BGP_AFI(*af), BGP_SAFI(*af));
1885
  }
1886
1887
  if (b.pos == b.end)
1888
    strcpy(b.end - 32, " ... <too long>");
1889
1890
  cli_msg(code, b.start);
1891
}
1892
1893
static void
1894
bgp_show_capabilities(struct bgp_proto *p UNUSED, struct bgp_caps *caps)
1895
{
1896
  struct bgp_af_caps *ac;
1897
  uint any_mp_bgp = 0;
1898
  uint any_gr_able = 0;
1899
  uint any_add_path = 0;
1900 d8022d26 Ondrej Zajicek (work)
  uint any_ext_next_hop = 0;
1901 256cc8ee Ondrej Zajicek (work)
  u32 *afl1 = alloca(caps->af_count * sizeof(u32));
1902
  u32 *afl2 = alloca(caps->af_count * sizeof(u32));
1903
  uint afn1, afn2;
1904
1905
  WALK_AF_CAPS(caps, ac)
1906
  {
1907
    any_mp_bgp |= ac->ready;
1908
    any_gr_able |= ac->gr_able;
1909
    any_add_path |= ac->add_path;
1910 d8022d26 Ondrej Zajicek (work)
    any_ext_next_hop |= ac->ext_next_hop;
1911 256cc8ee Ondrej Zajicek (work)
  }
1912
1913
  if (any_mp_bgp)
1914
  {
1915
    cli_msg(-1006, "      Multiprotocol");
1916
1917
    afn1 = 0;
1918
    WALK_AF_CAPS(caps, ac)
1919
      if (ac->ready)
1920
        afl1[afn1++] = ac->afi;
1921
1922
    bgp_show_afis(-1006, "        AF announced:", afl1, afn1);
1923
  }
1924
1925
  if (caps->route_refresh)
1926
    cli_msg(-1006, "      Route refresh");
1927
1928 d8022d26 Ondrej Zajicek (work)
  if (any_ext_next_hop)
1929
  {
1930
    cli_msg(-1006, "      Extended next hop");
1931
1932
    afn1 = 0;
1933
    WALK_AF_CAPS(caps, ac)
1934
      if (ac->ext_next_hop)
1935
        afl1[afn1++] = ac->afi;
1936
1937
    bgp_show_afis(-1006, "        IPv6 nexthop:", afl1, afn1);
1938
  }
1939
1940 256cc8ee Ondrej Zajicek (work)
  if (caps->ext_messages)
1941
    cli_msg(-1006, "      Extended message");
1942
1943
  if (caps->gr_aware)
1944
    cli_msg(-1006, "      Graceful restart");
1945
1946
  if (any_gr_able)
1947
  {
1948
    /* Continues from gr_aware */
1949
    cli_msg(-1006, "        Restart time: %u", caps->gr_time);
1950
    if (caps->gr_flags & BGP_GRF_RESTART)
1951
      cli_msg(-1006, "        Restart recovery");
1952
1953
    afn1 = afn2 = 0;
1954
    WALK_AF_CAPS(caps, ac)
1955
    {
1956
      if (ac->gr_able)
1957
        afl1[afn1++] = ac->afi;
1958
1959
      if (ac->gr_af_flags & BGP_GRF_FORWARDING)
1960
        afl2[afn2++] = ac->afi;
1961
    }
1962
1963
    bgp_show_afis(-1006, "        AF supported:", afl1, afn1);
1964
    bgp_show_afis(-1006, "        AF preserved:", afl2, afn2);
1965
  }
1966
1967
  if (caps->as4_support)
1968
    cli_msg(-1006, "      4-octet AS numbers");
1969
1970
  if (any_add_path)
1971
  {
1972
    cli_msg(-1006, "      ADD-PATH");
1973
1974
    afn1 = afn2 = 0;
1975
    WALK_AF_CAPS(caps, ac)
1976
    {
1977
      if (ac->add_path & BGP_ADD_PATH_RX)
1978
        afl1[afn1++] = ac->afi;
1979
1980
      if (ac->add_path & BGP_ADD_PATH_TX)
1981
        afl2[afn2++] = ac->afi;
1982
    }
1983
1984
    bgp_show_afis(-1006, "        RX:", afl1, afn1);
1985
    bgp_show_afis(-1006, "        TX:", afl2, afn2);
1986
  }
1987
1988
  if (caps->enhanced_refresh)
1989
    cli_msg(-1006, "      Enhanced refresh");
1990
}
1991
1992
static void
1993 b8113a5e Ondrej Zajicek
bgp_show_proto_info(struct proto *P)
1994
{
1995
  struct bgp_proto *p = (struct bgp_proto *) P;
1996
1997
  cli_msg(-1006, "  BGP state:          %s", bgp_state_dsc(p));
1998 53ffbff3 Ondrej Zajicek
  cli_msg(-1006, "    Neighbor address: %I%J", p->cf->remote_ip, p->cf->iface);
1999 51947659 Ondrej Zajicek
  cli_msg(-1006, "    Neighbor AS:      %u", p->remote_as);
2000 b8113a5e Ondrej Zajicek
2001 d15b0b0a Ondrej Zajicek (work)
  if (p->gr_active_num)
2002 0c791f87 Ondrej Zajicek
    cli_msg(-1006, "    Neighbor graceful restart active");
2003
2004 b8113a5e Ondrej Zajicek
  if (P->proto_state == PS_START)
2005 d15b0b0a Ondrej Zajicek (work)
  {
2006
    struct bgp_conn *oc = &p->outgoing_conn;
2007 b8113a5e Ondrej Zajicek
2008 d15b0b0a Ondrej Zajicek (work)
    if ((p->start_state < BSS_CONNECT) &&
2009
        (p->startup_timer->expires))
2010
      cli_msg(-1006, "    Error wait:       %d/%d",
2011
              p->startup_timer->expires - now, p->startup_delay);
2012 b8113a5e Ondrej Zajicek
2013 d15b0b0a Ondrej Zajicek (work)
    if ((oc->state == BS_ACTIVE) &&
2014
        (oc->connect_timer->expires))
2015
      cli_msg(-1006, "    Connect delay:    %d/%d",
2016
              oc->connect_timer->expires - now, p->cf->connect_delay_time);
2017 0c791f87 Ondrej Zajicek
2018 d15b0b0a Ondrej Zajicek (work)
    if (p->gr_active_num && p->gr_timer->expires)
2019
      cli_msg(-1006, "    Restart timer:    %d/-", p->gr_timer->expires - now);
2020
  }
2021 b8113a5e Ondrej Zajicek
  else if (P->proto_state == PS_UP)
2022 d15b0b0a Ondrej Zajicek (work)
  {
2023
    cli_msg(-1006, "    Neighbor ID:      %R", p->remote_id);
2024 256cc8ee Ondrej Zajicek (work)
    cli_msg(-1006, "    Local capabilities");
2025
    bgp_show_capabilities(p, p->conn->local_caps);
2026
    cli_msg(-1006, "    Neighbor capabilities");
2027
    bgp_show_capabilities(p, p->conn->remote_caps);
2028 d15b0b0a Ondrej Zajicek (work)
/* XXXX
2029 06e0d1b6 Ondrej Zajicek
      cli_msg(-1006, "    Session:          %s%s%s%s%s%s%s%s",
2030 b8113a5e Ondrej Zajicek
              p->is_internal ? "internal" : "external",
2031 51947659 Ondrej Zajicek
              p->cf->multihop ? " multihop" : "",
2032 b8113a5e Ondrej Zajicek
              p->rr_client ? " route-reflector" : "",
2033
              p->rs_client ? " route-server" : "",
2034 094d2bdb Ondrej Zajicek
              p->as4_session ? " AS4" : "",
2035
              p->add_path_rx ? " add-path-rx" : "",
2036 06e0d1b6 Ondrej Zajicek
              p->add_path_tx ? " add-path-tx" : "",
2037
              p->ext_messages ? " ext-messages" : "");
2038 d15b0b0a Ondrej Zajicek (work)
*/
2039
    cli_msg(-1006, "    Source address:   %I", p->source_addr);
2040
    cli_msg(-1006, "    Hold timer:       %d/%d",
2041 256cc8ee Ondrej Zajicek (work)
            tm_remains(p->conn->hold_timer), p->conn->hold_time);
2042 d15b0b0a Ondrej Zajicek (work)
    cli_msg(-1006, "    Keepalive timer:  %d/%d",
2043 256cc8ee Ondrej Zajicek (work)
            tm_remains(p->conn->keepalive_timer), p->conn->keepalive_time);
2044 d15b0b0a Ondrej Zajicek (work)
  }
2045 b8113a5e Ondrej Zajicek
2046 523f020b Ondrej Zajicek
  if ((p->last_error_class != BE_NONE) &&
2047 b8113a5e Ondrej Zajicek
      (p->last_error_class != BE_MAN_DOWN))
2048 d15b0b0a Ondrej Zajicek (work)
  {
2049
    const char *err1 = bgp_err_classes[p->last_error_class];
2050
    const char *err2 = bgp_last_errmsg(p);
2051
    cli_msg(-1006, "    Last error:       %s%s", err1, err2);
2052
  }
2053
2054
  {
2055
    /* XXXX ?? */
2056 ef57b70f Ondrej Zajicek (work)
    struct bgp_channel *c;
2057 d15b0b0a Ondrej Zajicek (work)
    WALK_LIST(c, p->p.channels)
2058 ef57b70f Ondrej Zajicek (work)
    {
2059
      channel_show_info(&c->c);
2060
2061
      if (c->igp_table_ip4)
2062
        cli_msg(-1006, "    IGP IPv4 table: %s", c->igp_table_ip4->name);
2063
2064
      if (c->igp_table_ip6)
2065
        cli_msg(-1006, "    IGP IPv6 table: %s", c->igp_table_ip6->name);
2066
    }
2067 d15b0b0a Ondrej Zajicek (work)
  }
2068 973399ae Martin Mares
}
2069
2070 d15b0b0a Ondrej Zajicek (work)
struct channel_class channel_bgp = {
2071
  .channel_size =        sizeof(struct bgp_channel),
2072
  .config_size =        sizeof(struct bgp_channel_config),
2073
  .init =                bgp_channel_init,
2074
  .start =                bgp_channel_start,
2075
  .shutdown =                bgp_channel_shutdown,
2076
  .cleanup =                bgp_channel_cleanup,
2077
  .reconfigure =        bgp_channel_reconfigure,
2078
};
2079
2080 2638249d Martin Mares
struct protocol proto_bgp = {
2081 4a591d4b Pavel Tvrdik
  .name =                 "BGP",
2082
  .template =                 "bgp%d",
2083
  .attr_class =         EAP_BGP,
2084
  .preference =         DEF_PREF_BGP,
2085 1e37e35c Ondrej Zajicek (work)
  .channel_mask =        NB_IP | NB_VPN | NB_FLOW,
2086 d15b0b0a Ondrej Zajicek (work)
  .proto_size =                sizeof(struct bgp_proto),
2087 2bbc3083 Ondrej Zajicek
  .config_size =        sizeof(struct bgp_config),
2088 d15b0b0a Ondrej Zajicek (work)
  .postconfig =                bgp_postconfig,
2089 4a591d4b Pavel Tvrdik
  .init =                 bgp_init,
2090
  .start =                 bgp_start,
2091
  .shutdown =                 bgp_shutdown,
2092
  .reconfigure =         bgp_reconfigure,
2093
  .copy_config =         bgp_copy_config,
2094
  .get_status =         bgp_get_status,
2095
  .get_attr =                 bgp_get_attr,
2096
  .get_route_info =         bgp_get_route_info,
2097
  .show_proto_info =         bgp_show_proto_info
2098 2638249d Martin Mares
};