Revision ef5081af proto/bgp/packets.c

View differences:

proto/bgp/packets.c
11 11
#undef LOCAL_DEBUG
12 12

  
13 13
#include <stdlib.h>
14
#include <stdio.h>
14 15

  
15 16
#include "nest/bird.h"
16 17
#include "nest/iface.h"
......
45 46

  
46 47
/* Table for state -> RFC 6608 FSM error subcodes */
47 48
static byte fsm_err_subcode[BS_MAX] = {
48
  [BS_OPENSENT] = 1,
49
  [BS_OPENCONFIRM] = 2,
50
  [BS_ESTABLISHED] = 3
49
        [BS_OPENSENT] = 1,
50
        [BS_OPENCONFIRM] = 2,
51
        [BS_ESTABLISHED] = 3
51 52
};
52 53

  
53 54

  
54 55
static struct bgp_channel *
55 56
bgp_get_channel(struct bgp_proto *p, u32 afi)
56 57
{
57
  uint i;
58
    uint i;
58 59

  
59
  for (i = 0; i < p->channel_count; i++)
60
    if (p->afi_map[i] == afi)
61
      return p->channel_map[i];
60
    for (i = 0; i < p->channel_count; i++)
61
        if (p->afi_map[i] == afi)
62
            return p->channel_map[i];
62 63

  
63
  return NULL;
64
    return NULL;
64 65
}
65 66

  
66 67
static inline void
67 68
put_af3(byte *buf, u32 id)
68 69
{
69
  put_u16(buf, id >> 16);
70
  buf[2] = id & 0xff;
70
    put_u16(buf, id >> 16);
71
    buf[2] = id & 0xff;
71 72
}
72 73

  
73 74
static inline void
74 75
put_af4(byte *buf, u32 id)
75 76
{
76
  put_u16(buf, id >> 16);
77
  buf[2] = 0;
78
  buf[3] = id & 0xff;
77
    put_u16(buf, id >> 16);
78
    buf[2] = 0;
79
    buf[3] = id & 0xff;
79 80
}
80 81

  
81 82
static inline u32
82 83
get_af3(byte *buf)
83 84
{
84
  return (get_u16(buf) << 16) | buf[2];
85
    return (get_u16(buf) << 16) | buf[2];
85 86
}
86 87

  
87 88
static inline u32
88 89
get_af4(byte *buf)
89 90
{
90
  return (get_u16(buf) << 16) | buf[3];
91
    return (get_u16(buf) << 16) | buf[3];
91 92
}
92 93

  
93 94
/*
......
109 110
static byte *
110 111
mrt_put_bgp4_hdr(byte *buf, struct bgp_conn *conn, int as4)
111 112
{
112
  struct bgp_proto *p = conn->bgp;
113
  uint v4 = ipa_is_ip4(p->cf->remote_ip);
114

  
115
  if (as4)
116
  {
117
    put_u32(buf+0, p->remote_as);
118
    put_u32(buf+4, p->public_as);
119
    buf+=8;
120
  }
121
  else
122
  {
123
    put_u16(buf+0, (p->remote_as <= 0xFFFF) ? p->remote_as : AS_TRANS);
124
    put_u16(buf+2, (p->public_as <= 0xFFFF) ? p->public_as : AS_TRANS);
125
    buf+=4;
126
  }
113
    struct bgp_proto *p = conn->bgp;
114
    uint v4 = ipa_is_ip4(p->cf->remote_ip);
115

  
116
    if (as4)
117
    {
118
        put_u32(buf+0, p->remote_as);
119
        put_u32(buf+4, p->public_as);
120
        buf+=8;
121
    }
122
    else
123
    {
124
        put_u16(buf+0, (p->remote_as <= 0xFFFF) ? p->remote_as : AS_TRANS);
125
        put_u16(buf+2, (p->public_as <= 0xFFFF) ? p->public_as : AS_TRANS);
126
        buf+=4;
127
    }
127 128

  
128
  put_u16(buf+0, (p->neigh && p->neigh->iface) ? p->neigh->iface->index : 0);
129
  put_u16(buf+2, v4 ? BGP_AFI_IPV4 : BGP_AFI_IPV6);
130
  buf+=4;
129
    put_u16(buf+0, (p->neigh && p->neigh->iface) ? p->neigh->iface->index : 0);
130
    put_u16(buf+2, v4 ? BGP_AFI_IPV4 : BGP_AFI_IPV6);
131
    buf+=4;
131 132

  
132
  if (v4)
133
  {
134
    buf = put_ip4(buf, conn->sk ? ipa_to_ip4(conn->sk->daddr) : IP4_NONE);
135
    buf = put_ip4(buf, conn->sk ? ipa_to_ip4(conn->sk->saddr) : IP4_NONE);
136
  }
137
  else
138
  {
139
    buf = put_ip6(buf, conn->sk ? ipa_to_ip6(conn->sk->daddr) : IP6_NONE);
140
    buf = put_ip6(buf, conn->sk ? ipa_to_ip6(conn->sk->saddr) : IP6_NONE);
141
  }
133
    if (v4)
134
    {
135
        buf = put_ip4(buf, conn->sk ? ipa_to_ip4(conn->sk->daddr) : IP4_NONE);
136
        buf = put_ip4(buf, conn->sk ? ipa_to_ip4(conn->sk->saddr) : IP4_NONE);
137
    }
138
    else
139
    {
140
        buf = put_ip6(buf, conn->sk ? ipa_to_ip6(conn->sk->daddr) : IP6_NONE);
141
        buf = put_ip6(buf, conn->sk ? ipa_to_ip6(conn->sk->saddr) : IP6_NONE);
142
    }
142 143

  
143
  return buf;
144
    return buf;
144 145
}
145 146

  
146 147
static void
147 148
mrt_dump_bgp_packet(struct bgp_conn *conn, byte *pkt, uint len)
148 149
{
149
  byte *buf = alloca(128+len);	/* 128 is enough for MRT headers */
150
  byte *bp = buf + MRTDUMP_HDR_LENGTH;
151
  int as4 = conn->bgp->as4_session;
150
    byte *buf = alloca(128+len);	/* 128 is enough for MRT headers */
151
    byte *bp = buf + MRTDUMP_HDR_LENGTH;
152
    int as4 = conn->bgp->as4_session;
152 153

  
153
  bp = mrt_put_bgp4_hdr(bp, conn, as4);
154
  memcpy(bp, pkt, len);
155
  bp += len;
156
  mrt_dump_message(&conn->bgp->p, BGP4MP, as4 ? BGP4MP_MESSAGE_AS4 : BGP4MP_MESSAGE,
157
		   buf, bp-buf);
154
    bp = mrt_put_bgp4_hdr(bp, conn, as4);
155
    memcpy(bp, pkt, len);
156
    bp += len;
157
    mrt_dump_message(&conn->bgp->p, BGP4MP, as4 ? BGP4MP_MESSAGE_AS4 : BGP4MP_MESSAGE,
158
                     buf, bp-buf);
158 159
}
159 160

  
160 161
static inline u16
161 162
convert_state(uint state)
162 163
{
163
  /* Convert state from our BS_* values to values used in MRTDump */
164
  return (state == BS_CLOSE) ? 1 : state + 1;
164
    /* Convert state from our BS_* values to values used in MRTDump */
165
    return (state == BS_CLOSE) ? 1 : state + 1;
165 166
}
166 167

  
167 168
void
168 169
mrt_dump_bgp_state_change(struct bgp_conn *conn, uint old, uint new)
169 170
{
170
  byte buf[128];
171
  byte *bp = buf + MRTDUMP_HDR_LENGTH;
171
    byte buf[128];
172
    byte *bp = buf + MRTDUMP_HDR_LENGTH;
172 173

  
173
  bp = mrt_put_bgp4_hdr(bp, conn, 1);
174
  put_u16(bp+0, convert_state(old));
175
  put_u16(bp+2, convert_state(new));
176
  bp += 4;
177
  mrt_dump_message(&conn->bgp->p, BGP4MP, BGP4MP_STATE_CHANGE_AS4, buf, bp-buf);
174
    bp = mrt_put_bgp4_hdr(bp, conn, 1);
175
    put_u16(bp+0, convert_state(old));
176
    put_u16(bp+2, convert_state(new));
177
    bp += 4;
178
    mrt_dump_message(&conn->bgp->p, BGP4MP, BGP4MP_STATE_CHANGE_AS4, buf, bp-buf);
178 179
}
179 180

  
180 181
static byte *
181 182
bgp_create_notification(struct bgp_conn *conn, byte *buf)
182 183
{
183
  struct bgp_proto *p = conn->bgp;
184
    struct bgp_proto *p = conn->bgp;
184 185

  
185
  BGP_TRACE(D_PACKETS, "Sending NOTIFICATION(code=%d.%d)", conn->notify_code, conn->notify_subcode);
186
  buf[0] = conn->notify_code;
187
  buf[1] = conn->notify_subcode;
188
  memcpy(buf+2, conn->notify_data, conn->notify_size);
189
  return buf + 2 + conn->notify_size;
186
    BGP_TRACE(D_PACKETS, "Sending NOTIFICATION(code=%d.%d)", conn->notify_code, conn->notify_subcode);
187
    buf[0] = conn->notify_code;
188
    buf[1] = conn->notify_subcode;
189
    memcpy(buf+2, conn->notify_data, conn->notify_size);
190
    return buf + 2 + conn->notify_size;
190 191
}
191 192

  
192 193

  
......
195 196
const struct bgp_af_caps *
196 197
bgp_find_af_caps(struct bgp_caps *caps, u32 afi)
197 198
{
198
  struct bgp_af_caps *ac;
199
    struct bgp_af_caps *ac;
199 200

  
200
  WALK_AF_CAPS(caps, ac)
201
    if (ac->afi == afi)
202
      return ac;
201
    WALK_AF_CAPS(caps, ac)
202
        if (ac->afi == afi)
203
            return ac;
203 204

  
204
  return NULL;
205
    return NULL;
205 206
}
206 207

  
207 208
static struct bgp_af_caps *
208 209
bgp_get_af_caps(struct bgp_caps *caps, u32 afi)
209 210
{
210
  struct bgp_af_caps *ac;
211
    struct bgp_af_caps *ac;
211 212

  
212
  WALK_AF_CAPS(caps, ac)
213
    if (ac->afi == afi)
214
      return ac;
213
    WALK_AF_CAPS(caps, ac)
214
        if (ac->afi == afi)
215
            return ac;
215 216

  
216
  ac = &caps->af_data[caps->af_count++];
217
  memset(ac, 0, sizeof(struct bgp_af_caps));
218
  ac->afi = afi;
217
    ac = &caps->af_data[caps->af_count++];
218
    memset(ac, 0, sizeof(struct bgp_af_caps));
219
    ac->afi = afi;
219 220

  
220
  return ac;
221
    return ac;
221 222
}
222 223

  
223 224
static int
224 225
bgp_af_caps_cmp(const void *X, const void *Y)
225 226
{
226
  const struct bgp_af_caps *x = X, *y = Y;
227
  return (x->afi < y->afi) ? -1 : (x->afi > y->afi) ? 1 : 0;
227
    const struct bgp_af_caps *x = X, *y = Y;
228
    return (x->afi < y->afi) ? -1 : (x->afi > y->afi) ? 1 : 0;
228 229
}
229 230

  
230 231

  
231 232
static byte *
232 233
bgp_write_capabilities(struct bgp_conn *conn, byte *buf)
233 234
{
234
  struct bgp_proto *p = conn->bgp;
235
  struct bgp_channel *c;
236
  struct bgp_caps *caps;
237
  struct bgp_af_caps *ac;
238
  uint any_ext_next_hop = 0;
239
  uint any_add_path = 0;
240
  byte *data;
241

  
242
  /* Prepare bgp_caps structure */
243

  
244
  int n = list_length(&p->p.channels);
245
  caps = mb_allocz(p->p.pool, sizeof(struct bgp_caps) + n * sizeof(struct bgp_af_caps));
246
  conn->local_caps = caps;
247

  
248
  caps->as4_support = p->cf->enable_as4;
249
  caps->ext_messages = p->cf->enable_extended_messages;
250
  caps->route_refresh = p->cf->enable_refresh;
251
  caps->enhanced_refresh = p->cf->enable_refresh;
252

  
253
  if (caps->as4_support)
254
    caps->as4_number = p->public_as;
255

  
256
  if (p->cf->gr_mode)
257
  {
258
    caps->gr_aware = 1;
259
    caps->gr_time = p->cf->gr_time;
260
    caps->gr_flags = p->p.gr_recovery ? BGP_GRF_RESTART : 0;
261
  }
262

  
263
  /* Allocate and fill per-AF fields */
264
  WALK_LIST(c, p->p.channels)
265
  {
266
    ac = &caps->af_data[caps->af_count++];
267
    ac->afi = c->afi;
268
    ac->ready = 1;
235
    struct bgp_proto *p = conn->bgp;
236
    struct bgp_channel *c;
237
    struct bgp_caps *caps;
238
    struct bgp_af_caps *ac;
239
    uint any_ext_next_hop = 0;
240
    uint any_add_path = 0;
241
    byte *data;
269 242

  
270
    ac->ext_next_hop = bgp_channel_is_ipv4(c) && c->cf->ext_next_hop;
271
    any_ext_next_hop |= ac->ext_next_hop;
243
    /* Prepare bgp_caps structure */
272 244

  
273
    ac->add_path = c->cf->add_path;
274
    any_add_path |= ac->add_path;
245
    int n = list_length(&p->p.channels);
246
    caps = mb_allocz(p->p.pool, sizeof(struct bgp_caps) + n * sizeof(struct bgp_af_caps));
247
    conn->local_caps = caps;
275 248

  
276
    if (c->cf->gr_able)
277
    {
278
      ac->gr_able = 1;
249
    caps->as4_support = p->cf->enable_as4;
250
    caps->ext_messages = p->cf->enable_extended_messages;
251
    caps->route_refresh = p->cf->enable_refresh;
252
    caps->enhanced_refresh = p->cf->enable_refresh;
253

  
254
    if (caps->as4_support)
255
        caps->as4_number = p->public_as;
279 256

  
280
      if (p->p.gr_recovery)
281
	ac->gr_af_flags |= BGP_GRF_FORWARDING;
257
    if (p->cf->gr_mode)
258
    {
259
        caps->gr_aware = 1;
260
        caps->gr_time = p->cf->gr_time;
261
        caps->gr_flags = p->p.gr_recovery ? BGP_GRF_RESTART : 0;
282 262
    }
283
  }
284 263

  
285
  /* Sort capability fields by AFI/SAFI */
286
  qsort(caps->af_data, caps->af_count, sizeof(struct bgp_af_caps), bgp_af_caps_cmp);
264
    /* Allocate and fill per-AF fields */
265
    WALK_LIST(c, p->p.channels)
266
    {
267
        ac = &caps->af_data[caps->af_count++];
268
        ac->afi = c->afi;
269
        ac->ready = 1;
287 270

  
271
        ac->ext_next_hop = bgp_channel_is_ipv4(c) && c->cf->ext_next_hop;
272
        any_ext_next_hop |= ac->ext_next_hop;
288 273

  
289
  /* Create capability list in buffer */
274
        ac->add_path = c->cf->add_path;
275
        any_add_path |= ac->add_path;
290 276

  
291
  /*
292
   * Note that max length is ~ 20+14*af_count. With max 12 channels that is
293
   * 188. Option limit is 253 and buffer size is 4096, so we cannot overflow
294
   * unless we add new capabilities or more AFs.
295
   */
277
        if (c->cf->gr_able)
278
        {
279
            ac->gr_able = 1;
296 280

  
297
  WALK_AF_CAPS(caps, ac)
298
    if (ac->ready)
299
    {
300
      *buf++ = 1;		/* Capability 1: Multiprotocol extensions */
301
      *buf++ = 4;		/* Capability data length */
302
      put_af4(buf, ac->afi);
303
      buf += 4;
281
            if (p->p.gr_recovery)
282
                ac->gr_af_flags |= BGP_GRF_FORWARDING;
283
        }
304 284
    }
305 285

  
306
  if (caps->route_refresh)
307
  {
308
    *buf++ = 2;			/* Capability 2: Support for route refresh */
309
    *buf++ = 0;			/* Capability data length */
310
  }
286
    /* Sort capability fields by AFI/SAFI */
287
    qsort(caps->af_data, caps->af_count, sizeof(struct bgp_af_caps), bgp_af_caps_cmp);
311 288

  
312
  if (any_ext_next_hop)
313
  {
314
    *buf++ = 5;			/* Capability 5: Support for extended next hop */
315
    *buf++ = 0;			/* Capability data length, will be fixed later */
316
    data = buf;
317 289

  
318
    WALK_AF_CAPS(caps, ac)
319
      if (ac->ext_next_hop)
320
      {
321
	put_af4(buf, ac->afi);
322
	put_u16(buf+4, BGP_AFI_IPV6);
323
	buf += 6;
324
      }
325

  
326
    data[-1] = buf - data;
327
  }
328

  
329
  if (caps->ext_messages)
330
  {
331
    *buf++ = 6;			/* Capability 6: Support for extended messages */
332
    *buf++ = 0;			/* Capability data length */
333
  }
334

  
335
  if (caps->gr_aware)
336
  {
337
    *buf++ = 64;		/* Capability 64: Support for graceful restart */
338
    *buf++ = 0;			/* Capability data length, will be fixed later */
339
    data = buf;
340

  
341
    put_u16(buf, caps->gr_time);
342
    buf[0] |= caps->gr_flags;
343
    buf += 2;
290
    /* Create capability list in buffer */
344 291

  
345
    WALK_AF_CAPS(caps, ac)
346
      if (ac->gr_able)
347
      {
348
	put_af3(buf, ac->afi);
349
	buf[3] = ac->gr_af_flags;
350
	buf += 4;
351
      }
352

  
353
    data[-1] = buf - data;
354
  }
355

  
356
  if (caps->as4_support)
357
  {
358
    *buf++ = 65;		/* Capability 65: Support for 4-octet AS number */
359
    *buf++ = 4;			/* Capability data length */
360
    put_u32(buf, p->public_as);
361
    buf += 4;
362
  }
363

  
364
  if (any_add_path)
365
  {
366
    *buf++ = 69;		/* Capability 69: Support for ADD-PATH */
367
    *buf++ = 0;			/* Capability data length, will be fixed later */
368
    data = buf;
292
    /*
293
     * Note that max length is ~ 20+14*af_count. With max 12 channels that is
294
     * 188. Option limit is 253 and buffer size is 4096, so we cannot overflow
295
     * unless we add new capabilities or more AFs.
296
     */
369 297

  
370 298
    WALK_AF_CAPS(caps, ac)
371
      if (ac->add_path)
372
      {
373
	put_af3(buf, ac->afi);
374
	buf[3] = ac->add_path;
375
	buf += 4;
376
      }
299
        if (ac->ready)
300
        {
301
            *buf++ = 1;		/* Capability 1: Multiprotocol extensions */
302
            *buf++ = 4;		/* Capability data length */
303
            put_af4(buf, ac->afi);
304
            buf += 4;
305
        }
306

  
307
    if (caps->route_refresh)
308
    {
309
        *buf++ = 2;			/* Capability 2: Support for route refresh */
310
        *buf++ = 0;			/* Capability data length */
311
    }
377 312

  
378
    data[-1] = buf - data;
379
  }
313
    if (any_ext_next_hop)
314
    {
315
        *buf++ = 5;			/* Capability 5: Support for extended next hop */
316
        *buf++ = 0;			/* Capability data length, will be fixed later */
317
        data = buf;
318

  
319
        WALK_AF_CAPS(caps, ac)
320
            if (ac->ext_next_hop)
321
            {
322
                put_af4(buf, ac->afi);
323
                put_u16(buf+4, BGP_AFI_IPV6);
324
                buf += 6;
325
            }
326

  
327
        data[-1] = buf - data;
328
    }
380 329

  
381
  if (caps->enhanced_refresh)
382
  {
383
    *buf++ = 70;		/* Capability 70: Support for enhanced route refresh */
384
    *buf++ = 0;			/* Capability data length */
385
  }
330
    if (caps->ext_messages)
331
    {
332
        *buf++ = 6;			/* Capability 6: Support for extended messages */
333
        *buf++ = 0;			/* Capability data length */
334
    }
386 335

  
387
  return buf;
336
    if (caps->gr_aware)
337
    {
338
        *buf++ = 64;		/* Capability 64: Support for graceful restart */
339
        *buf++ = 0;			/* Capability data length, will be fixed later */
340
        data = buf;
341

  
342
        put_u16(buf, caps->gr_time);
343
        buf[0] |= caps->gr_flags;
344
        buf += 2;
345

  
346
        WALK_AF_CAPS(caps, ac)
347
            if (ac->gr_able)
348
            {
349
                put_af3(buf, ac->afi);
350
                buf[3] = ac->gr_af_flags;
351
                buf += 4;
352
            }
353

  
354
        data[-1] = buf - data;
355
    }
356

  
357
    if (caps->as4_support)
358
    {
359
        *buf++ = 65;		/* Capability 65: Support for 4-octet AS number */
360
        *buf++ = 4;			/* Capability data length */
361
        put_u32(buf, p->public_as);
362
        buf += 4;
363
    }
364

  
365
    if (any_add_path)
366
    {
367
        *buf++ = 69;		/* Capability 69: Support for ADD-PATH */
368
        *buf++ = 0;			/* Capability data length, will be fixed later */
369
        data = buf;
370

  
371
        WALK_AF_CAPS(caps, ac)
372
            if (ac->add_path)
373
            {
374
                put_af3(buf, ac->afi);
375
                buf[3] = ac->add_path;
376
                buf += 4;
377
            }
378

  
379
        data[-1] = buf - data;
380
    }
381

  
382
    if (caps->enhanced_refresh)
383
    {
384
        *buf++ = 70;		/* Capability 70: Support for enhanced route refresh */
385
        *buf++ = 0;			/* Capability data length */
386
    }
387

  
388
    return buf;
388 389
}
389 390

  
390 391
static void
391 392
bgp_read_capabilities(struct bgp_conn *conn, struct bgp_caps *caps, byte *pos, int len)
392 393
{
393
  struct bgp_proto *p = conn->bgp;
394
  struct bgp_af_caps *ac;
395
  int i, cl;
396
  u32 af;
397

  
398
  while (len > 0)
399
  {
400
    if (len < 2 || len < (2 + pos[1]))
401
      goto err;
402

  
403
    /* Capability length */
404
    cl = pos[1];
405

  
406
    /* Capability type */
407
    switch (pos[0])
408
    {
409
    case  1: /* Multiprotocol capability, RFC 4760 */
410
      if (cl != 4)
411
	goto err;
412

  
413
      af = get_af4(pos+2);
414
      ac = bgp_get_af_caps(caps, af);
415
      ac->ready = 1;
416
      break;
417

  
418
    case  2: /* Route refresh capability, RFC 2918 */
419
      if (cl != 0)
420
	goto err;
421

  
422
      caps->route_refresh = 1;
423
      break;
424

  
425
    case  5: /* Extended next hop encoding capability, RFC 5549 */
426
      if (cl % 6)
427
	goto err;
428

  
429
      for (i = 0; i < cl; i += 6)
430
      {
431
	/* Specified only for IPv4 prefixes with IPv6 next hops */
432
	if ((get_u16(pos+2+i+0) != BGP_AFI_IPV4) ||
433
	    (get_u16(pos+2+i+4) != BGP_AFI_IPV6))
434
	  continue;
435

  
436
	af = get_af4(pos+2+i);
437
	ac = bgp_get_af_caps(caps, af);
438
	ac->ext_next_hop = 1;
439
      }
440
      break;
441

  
442
    case  6: /* Extended message length capability, RFC draft */
443
      if (cl != 0)
444
	goto err;
445

  
446
      caps->ext_messages = 1;
447
      break;
448

  
449
    case 64: /* Graceful restart capability, RFC 4724 */
450
      if (cl % 4 != 2)
451
	goto err;
452

  
453
      /* Only the last instance is valid */
454
      WALK_AF_CAPS(caps, ac)
455
      {
456
	ac->gr_able = 0;
457
	ac->gr_af_flags = 0;
458
      }
459

  
460
      caps->gr_aware = 1;
461
      caps->gr_flags = pos[2] & 0xf0;
462
      caps->gr_time = get_u16(pos + 2) & 0x0fff;
463

  
464
      for (i = 2; i < cl; i += 4)
465
      {
466
	af = get_af3(pos+2+i);
467
	ac = bgp_get_af_caps(caps, af);
468
	ac->gr_able = 1;
469
	ac->gr_af_flags = pos[2+i+3];
470
      }
471
      break;
472

  
473
    case 65: /* AS4 capability, RFC 6793 */
474
      if (cl != 4)
475
	goto err;
476

  
477
      caps->as4_support = 1;
478
      caps->as4_number = get_u32(pos + 2);
479
      break;
480

  
481
    case 69: /* ADD-PATH capability, RFC 7911 */
482
      if (cl % 4)
483
	goto err;
484

  
485
      for (i = 0; i < cl; i += 4)
486
      {
487
	byte val = pos[2+i+3];
488
	if (!val || (val > BGP_ADD_PATH_FULL))
489
	{
490
	  log(L_WARN "%s: Got ADD-PATH capability with unknown value %u, ignoring",
491
	      p->p.name, val);
492
	  break;
493
	}
494
      }
495

  
496
      for (i = 0; i < cl; i += 4)
497
      {
498
	af = get_af3(pos+2+i);
499
	ac = bgp_get_af_caps(caps, af);
500
	ac->add_path = pos[2+i+3];
501
      }
502
      break;
503

  
504
    case 70: /* Enhanced route refresh capability, RFC 7313 */
505
      if (cl != 0)
506
	goto err;
507

  
508
      caps->enhanced_refresh = 1;
509
      break;
510

  
511
      /* We can safely ignore all other capabilities */
512
    }
513

  
514
    ADVANCE(pos, len, 2 + cl);
515
  }
516
  return;
517

  
518
err:
519
  bgp_error(conn, 2, 0, NULL, 0);
520
  return;
394
    struct bgp_proto *p = conn->bgp;
395
    struct bgp_af_caps *ac;
396
    int i, cl;
397
    u32 af;
398

  
399
    while (len > 0)
400
    {
401
        if (len < 2 || len < (2 + pos[1]))
402
            goto err;
403

  
404
        /* Capability length */
405
        cl = pos[1];
406

  
407
        /* Capability type */
408
        switch (pos[0])
409
        {
410
            case  1: /* Multiprotocol capability, RFC 4760 */
411
                if (cl != 4)
412
                    goto err;
413

  
414
                af = get_af4(pos+2);
415
                ac = bgp_get_af_caps(caps, af);
416
                ac->ready = 1;
417
                break;
418

  
419
            case  2: /* Route refresh capability, RFC 2918 */
420
                if (cl != 0)
421
                    goto err;
422

  
423
                caps->route_refresh = 1;
424
                break;
425

  
426
            case  5: /* Extended next hop encoding capability, RFC 5549 */
427
                if (cl % 6)
428
                    goto err;
429

  
430
                for (i = 0; i < cl; i += 6)
431
                {
432
                    /* Specified only for IPv4 prefixes with IPv6 next hops */
433
                    if ((get_u16(pos+2+i+0) != BGP_AFI_IPV4) ||
434
                        (get_u16(pos+2+i+4) != BGP_AFI_IPV6))
435
                        continue;
436

  
437
                    af = get_af4(pos+2+i);
438
                    ac = bgp_get_af_caps(caps, af);
439
                    ac->ext_next_hop = 1;
440
                }
441
                break;
442

  
443
            case  6: /* Extended message length capability, RFC draft */
444
                if (cl != 0)
445
                    goto err;
446

  
447
                caps->ext_messages = 1;
448
                break;
449

  
450
            case 64: /* Graceful restart capability, RFC 4724 */
451
                if (cl % 4 != 2)
452
                    goto err;
453

  
454
                /* Only the last instance is valid */
455
                WALK_AF_CAPS(caps, ac)
456
                {
457
                    ac->gr_able = 0;
458
                    ac->gr_af_flags = 0;
459
                }
460

  
461
                caps->gr_aware = 1;
462
                caps->gr_flags = pos[2] & 0xf0;
463
                caps->gr_time = get_u16(pos + 2) & 0x0fff;
464

  
465
                for (i = 2; i < cl; i += 4)
466
                {
467
                    af = get_af3(pos+2+i);
468
                    ac = bgp_get_af_caps(caps, af);
469
                    ac->gr_able = 1;
470
                    ac->gr_af_flags = pos[2+i+3];
471
                }
472
                break;
473

  
474
            case 65: /* AS4 capability, RFC 6793 */
475
                if (cl != 4)
476
                    goto err;
477

  
478
                caps->as4_support = 1;
479
                caps->as4_number = get_u32(pos + 2);
480
                break;
481

  
482
            case 69: /* ADD-PATH capability, RFC 7911 */
483
                if (cl % 4)
484
                    goto err;
485

  
486
                for (i = 0; i < cl; i += 4)
487
                {
488
                    byte val = pos[2+i+3];
489
                    if (!val || (val > BGP_ADD_PATH_FULL))
490
                    {
491
                        log(L_WARN "%s: Got ADD-PATH capability with unknown value %u, ignoring",
492
                                p->p.name, val);
493
                        break;
494
                    }
495
                }
496

  
497
                for (i = 0; i < cl; i += 4)
498
                {
499
                    af = get_af3(pos+2+i);
500
                    ac = bgp_get_af_caps(caps, af);
501
                    ac->add_path = pos[2+i+3];
502
                }
503
                break;
504

  
505
            case 70: /* Enhanced route refresh capability, RFC 7313 */
506
                if (cl != 0)
507
                    goto err;
508

  
509
                caps->enhanced_refresh = 1;
510
                break;
511

  
512
                /* We can safely ignore all other capabilities */
513
        }
514

  
515
        ADVANCE(pos, len, 2 + cl);
516
    }
517
    return;
518

  
519
    err:
520
    bgp_error(conn, 2, 0, NULL, 0);
521
    return;
521 522
}
522 523

  
523 524
static int
524 525
bgp_read_options(struct bgp_conn *conn, byte *pos, int len)
525 526
{
526
  struct bgp_proto *p = conn->bgp;
527
  struct bgp_caps *caps;
528
  int ol;
529

  
530
  /* Max number of announced AFIs is limited by max option length (255) */
531
  caps = alloca(sizeof(struct bgp_caps) + 64 * sizeof(struct bgp_af_caps));
532
  memset(caps, 0, sizeof(struct bgp_caps));
527
    struct bgp_proto *p = conn->bgp;
528
    struct bgp_caps *caps;
529
    int ol;
533 530

  
534
  while (len > 0)
535
  {
536
    if ((len < 2) || (len < (2 + pos[1])))
537
    { bgp_error(conn, 2, 0, NULL, 0); return -1; }
531
    /* Max number of announced AFIs is limited by max option length (255) */
532
    caps = alloca(sizeof(struct bgp_caps) + 64 * sizeof(struct bgp_af_caps));
533
    memset(caps, 0, sizeof(struct bgp_caps));
538 534

  
539
    ol = pos[1];
540
    if (pos[0] == 2)
535
    while (len > 0)
541 536
    {
542
      /* BGP capabilities, RFC 5492 */
543
      if (p->cf->capabilities)
544
	bgp_read_capabilities(conn, caps, pos + 2, ol);
545
    }
546
    else
547
    {
548
      /* Unknown option */
549
      bgp_error(conn, 2, 4, pos, ol); /* FIXME: ol or ol+2 ? */
550
      return -1;
537
        if ((len < 2) || (len < (2 + pos[1])))
538
        { bgp_error(conn, 2, 0, NULL, 0); return -1; }
539

  
540
        ol = pos[1];
541
        if (pos[0] == 2)
542
        {
543
            /* BGP capabilities, RFC 5492 */
544
            if (p->cf->capabilities)
545
                bgp_read_capabilities(conn, caps, pos + 2, ol);
546
        }
547
        else
548
        {
549
            /* Unknown option */
550
            bgp_error(conn, 2, 4, pos, ol); /* FIXME: ol or ol+2 ? */
551
            return -1;
552
        }
553

  
554
        ADVANCE(pos, len, 2 + ol);
551 555
    }
552 556

  
553
    ADVANCE(pos, len, 2 + ol);
554
  }
557
    uint n = sizeof(struct bgp_caps) + caps->af_count * sizeof(struct bgp_af_caps);
558
    conn->remote_caps = mb_allocz(p->p.pool, n);
559
    memcpy(conn->remote_caps, caps, n);
555 560

  
556
  uint n = sizeof(struct bgp_caps) + caps->af_count * sizeof(struct bgp_af_caps);
557
  conn->remote_caps = mb_allocz(p->p.pool, n);
558
  memcpy(conn->remote_caps, caps, n);
559

  
560
  return 0;
561
    return 0;
561 562
}
562 563

  
563 564
static byte *
564 565
bgp_create_open(struct bgp_conn *conn, byte *buf)
565 566
{
566
  struct bgp_proto *p = conn->bgp;
567
    struct bgp_proto *p = conn->bgp;
567 568

  
568
  BGP_TRACE(D_PACKETS, "Sending OPEN(ver=%d,as=%d,hold=%d,id=%08x)",
569
	    BGP_VERSION, p->public_as, p->cf->hold_time, p->local_id);
569
    BGP_TRACE(D_PACKETS, "Sending OPEN(ver=%d,as=%d,hold=%d,id=%08x)",
570
              BGP_VERSION, p->public_as, p->cf->hold_time, p->local_id);
570 571

  
571
  buf[0] = BGP_VERSION;
572
  put_u16(buf+1, (p->public_as < 0xFFFF) ? p->public_as : AS_TRANS);
573
  put_u16(buf+3, p->cf->hold_time);
574
  put_u32(buf+5, p->local_id);
572
    buf[0] = BGP_VERSION;
573
    put_u16(buf+1, (p->public_as < 0xFFFF) ? p->public_as : AS_TRANS);
574
    put_u16(buf+3, p->cf->hold_time);
575
    put_u32(buf+5, p->local_id);
575 576

  
576
  if (p->cf->capabilities)
577
  {
578
    /* Prepare local_caps and write capabilities to buffer */
579
    byte *end = bgp_write_capabilities(conn, buf+12);
580
    uint len = end - (buf+12);
577
    if (p->cf->capabilities)
578
    {
579
        /* Prepare local_caps and write capabilities to buffer */
580
        byte *end = bgp_write_capabilities(conn, buf+12);
581
        uint len = end - (buf+12);
581 582

  
582
    buf[9] = len + 2;		/* Optional parameters length */
583
    buf[10] = 2;		/* Option 2: Capability list */
584
    buf[11] = len;		/* Option data length */
583
        buf[9] = len + 2;		/* Optional parameters length */
584
        buf[10] = 2;		/* Option 2: Capability list */
585
        buf[11] = len;		/* Option data length */
585 586

  
586
    return end;
587
  }
588
  else
589
  {
590
    /* Prepare empty local_caps */
591
    conn->local_caps = mb_allocz(p->p.pool, sizeof(struct bgp_caps));
587
        return end;
588
    }
589
    else
590
    {
591
        /* Prepare empty local_caps */
592
        conn->local_caps = mb_allocz(p->p.pool, sizeof(struct bgp_caps));
592 593

  
593
    buf[9] = 0;			/* No optional parameters */
594
    return buf + 10;
595
  }
594
        buf[9] = 0;			/* No optional parameters */
595
        return buf + 10;
596
    }
596 597

  
597
  return buf;
598
    return buf;
598 599
}
599 600

  
600 601
static void
601 602
bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len)
602 603
{
603
  struct bgp_proto *p = conn->bgp;
604
  struct bgp_conn *other;
605
  u32 asn, hold, id;
604
    struct bgp_proto *p = conn->bgp;
605
    struct bgp_conn *other;
606
    u32 asn, hold, id;
606 607

  
607
  /* Check state */
608
  if (conn->state != BS_OPENSENT)
609
  { bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0); return; }
608
    /* Check state */
609
    if (conn->state != BS_OPENSENT)
610
    { bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0); return; }
610 611

  
611
  /* Check message contents */
612
  if (len < 29 || len != 29 + (uint) pkt[28])
613
  { bgp_error(conn, 1, 2, pkt+16, 2); return; }
612
    /* Check message contents */
613
    if (len < 29 || len != 29 + (uint) pkt[28])
614
    { bgp_error(conn, 1, 2, pkt+16, 2); return; }
614 615

  
615
  if (pkt[19] != BGP_VERSION)
616
  { u16 val = BGP_VERSION; bgp_error(conn, 2, 1, (byte *) &val, 2); return; }
616
    if (pkt[19] != BGP_VERSION)
617
    { u16 val = BGP_VERSION; bgp_error(conn, 2, 1, (byte *) &val, 2); return; }
617 618

  
618
  asn = get_u16(pkt+20);
619
  hold = get_u16(pkt+22);
620
  id = get_u32(pkt+24);
621
  BGP_TRACE(D_PACKETS, "Got OPEN(as=%d,hold=%d,id=%R)", asn, hold, id);
619
    asn = get_u16(pkt+20);
620
    hold = get_u16(pkt+22);
621
    id = get_u32(pkt+24);
622
    BGP_TRACE(D_PACKETS, "Got OPEN(as=%d,hold=%d,id=%R)", asn, hold, id);
622 623

  
623
  if (bgp_read_options(conn, pkt+29, pkt[28]) < 0)
624
    return;
624
    if (bgp_read_options(conn, pkt+29, pkt[28]) < 0)
625
        return;
625 626

  
626
  if (hold > 0 && hold < 3)
627
  { bgp_error(conn, 2, 6, pkt+22, 2); return; }
628

  
629
  /* RFC 6286 2.2 - router ID is nonzero and AS-wide unique */
630
  if (!id || (p->is_internal && id == p->local_id))
631
  { bgp_error(conn, 2, 3, pkt+24, -4); return; }
632

  
633
  struct bgp_caps *caps = conn->remote_caps;
634

  
635
  if (caps->as4_support)
636
  {
637
    u32 as4 = caps->as4_number;
638

  
639
    if ((as4 != asn) && (asn != AS_TRANS))
640
      log(L_WARN "%s: Peer advertised inconsistent AS numbers", p->p.name);
641

  
642
    if (as4 != p->remote_as)
643
    { as4 = htonl(as4); bgp_error(conn, 2, 2, (byte *) &as4, 4); return; }
644
  }
645
  else
646
  {
647
    if (asn != p->remote_as)
648
    { bgp_error(conn, 2, 2, pkt+20, 2); return; }
649
  }
650

  
651
  /* Check the other connection */
652
  other = (conn == &p->outgoing_conn) ? &p->incoming_conn : &p->outgoing_conn;
653
  switch (other->state)
654
  {
655
  case BS_CONNECT:
656
  case BS_ACTIVE:
657
    /* Stop outgoing connection attempts */
658
    bgp_conn_enter_idle_state(other);
659
    break;
660

  
661
  case BS_IDLE:
662
  case BS_OPENSENT:
663
  case BS_CLOSE:
664
    break;
665

  
666
  case BS_OPENCONFIRM:
667
    /*
668
     * Description of collision detection rules in RFC 4271 is confusing and
669
     * contradictory, but it is essentially:
670
     *
671
     * 1. Router with higher ID is dominant
672
     * 2. If both have the same ID, router with higher ASN is dominant [RFC6286]
673
     * 3. When both connections are in OpenConfirm state, one initiated by
674
     *    the dominant router is kept.
675
     *
676
     * The first line in the expression below evaluates whether the neighbor
677
     * is dominant, the second line whether the new connection was initiated
678
     * by the neighbor. If both are true (or both are false), we keep the new
679
     * connection, otherwise we keep the old one.
680
     */
681
    if (((p->local_id < id) || ((p->local_id == id) && (p->public_as < p->remote_as)))
682
	== (conn == &p->incoming_conn))
683
    {
684
      /* Should close the other connection */
685
      BGP_TRACE(D_EVENTS, "Connection collision, giving up the other connection");
686
      bgp_error(other, 6, 7, NULL, 0);
687
      break;
688
    }
689
    /* Fall thru */
690
  case BS_ESTABLISHED:
691
    /* Should close this connection */
692
    BGP_TRACE(D_EVENTS, "Connection collision, giving up this connection");
693
    bgp_error(conn, 6, 7, NULL, 0);
694
    return;
627
    if (hold > 0 && hold < 3)
628
    { bgp_error(conn, 2, 6, pkt+22, 2); return; }
629

  
630
    /* RFC 6286 2.2 - router ID is nonzero and AS-wide unique */
631
    if (!id || (p->is_internal && id == p->local_id))
632
    { bgp_error(conn, 2, 3, pkt+24, -4); return; }
695 633

  
696
  default:
697
    bug("bgp_rx_open: Unknown state");
698
  }
634
    struct bgp_caps *caps = conn->remote_caps;
699 635

  
700
  /* Update our local variables */
701
  conn->hold_time = MIN(hold, p->cf->hold_time);
702
  conn->keepalive_time = p->cf->keepalive_time ? : conn->hold_time / 3;
703
  conn->as4_session = conn->local_caps->as4_support && caps->as4_support;
704
  conn->ext_messages = conn->local_caps->ext_messages && caps->ext_messages;
705
  p->remote_id = id;
636
    if (caps->as4_support)
637
    {
638
        u32 as4 = caps->as4_number;
639

  
640
        if ((as4 != asn) && (asn != AS_TRANS))
641
            log(L_WARN "%s: Peer advertised inconsistent AS numbers", p->p.name);
642

  
643
        if (as4 != p->remote_as)
644
        { as4 = htonl(as4); bgp_error(conn, 2, 2, (byte *) &as4, 4); return; }
645
    }
646
    else
647
    {
648
        if (asn != p->remote_as)
649
        { bgp_error(conn, 2, 2, pkt+20, 2); return; }
650
    }
651

  
652
    /* Check the other connection */
653
    other = (conn == &p->outgoing_conn) ? &p->incoming_conn : &p->outgoing_conn;
654
    switch (other->state)
655
    {
656
        case BS_CONNECT:
657
        case BS_ACTIVE:
658
            /* Stop outgoing connection attempts */
659
            bgp_conn_enter_idle_state(other);
660
            break;
661

  
662
        case BS_IDLE:
663
        case BS_OPENSENT:
664
        case BS_CLOSE:
665
            break;
666

  
667
        case BS_OPENCONFIRM:
668
            /*
669
             * Description of collision detection rules in RFC 4271 is confusing and
670
             * contradictory, but it is essentially:
671
             *
672
             * 1. Router with higher ID is dominant
673
             * 2. If both have the same ID, router with higher ASN is dominant [RFC6286]
674
             * 3. When both connections are in OpenConfirm state, one initiated by
675
             *    the dominant router is kept.
676
             *
677
             * The first line in the expression below evaluates whether the neighbor
678
             * is dominant, the second line whether the new connection was initiated
679
             * by the neighbor. If both are true (or both are false), we keep the new
680
             * connection, otherwise we keep the old one.
681
             */
682
            if (((p->local_id < id) || ((p->local_id == id) && (p->public_as < p->remote_as)))
683
                == (conn == &p->incoming_conn))
684
            {
685
                /* Should close the other connection */
686
                BGP_TRACE(D_EVENTS, "Connection collision, giving up the other connection");
687
                bgp_error(other, 6, 7, NULL, 0);
688
                break;
689
            }
690
            /* Fall thru */
691
        case BS_ESTABLISHED:
692
            /* Should close this connection */
693
            BGP_TRACE(D_EVENTS, "Connection collision, giving up this connection");
694
            bgp_error(conn, 6, 7, NULL, 0);
695
            return;
696

  
697
        default:
698
            bug("bgp_rx_open: Unknown state");
699
    }
700

  
701
    /* Update our local variables */
702
    conn->hold_time = MIN(hold, p->cf->hold_time);
703
    conn->keepalive_time = p->cf->keepalive_time ? : conn->hold_time / 3;
704
    conn->as4_session = conn->local_caps->as4_support && caps->as4_support;
705
    conn->ext_messages = conn->local_caps->ext_messages && caps->ext_messages;
706
    p->remote_id = id;
706 707

  
707
  DBG("BGP: Hold timer set to %d, keepalive to %d, AS to %d, ID to %x, AS4 session to %d\n",
708
      conn->hold_time, conn->keepalive_time, p->remote_as, p->remote_id, conn->as4_session);
708
    DBG("BGP: Hold timer set to %d, keepalive to %d, AS to %d, ID to %x, AS4 session to %d\n",
709
        conn->hold_time, conn->keepalive_time, p->remote_as, p->remote_id, conn->as4_session);
709 710

  
710
  bgp_schedule_packet(conn, NULL, PKT_KEEPALIVE);
711
  bgp_start_timer(conn->hold_timer, conn->hold_time);
712
  bgp_conn_enter_openconfirm_state(conn);
711
    bgp_schedule_packet(conn, NULL, PKT_KEEPALIVE);
712
    bgp_start_timer(conn->hold_timer, conn->hold_time);
713
    bgp_conn_enter_openconfirm_state(conn);
713 714
}
714 715

  
715 716

  
......
735 736
static void
736 737
bgp_apply_next_hop(struct bgp_parse_state *s, rta *a, ip_addr gw, ip_addr ll)
737 738
{
738
  struct bgp_proto *p = s->proto;
739
  struct bgp_channel *c = s->channel;
739
    struct bgp_proto *p = s->proto;
740
    struct bgp_channel *c = s->channel;
740 741

  
741
  if (c->cf->gw_mode == GW_DIRECT)
742
  {
743
    neighbor *nbr = NULL;
742
    if (c->cf->gw_mode == GW_DIRECT)
743
    {
744
        neighbor *nbr = NULL;
744 745

  
745
    /* GW_DIRECT -> single_hop -> p->neigh != NULL */
746
    if (ipa_nonzero(gw))
747
      nbr = neigh_find2(&p->p, &gw, NULL, 0);
748
    else if (ipa_nonzero(ll))
749
      nbr = neigh_find2(&p->p, &ll, p->neigh->iface, 0);
746
        /* GW_DIRECT -> single_hop -> p->neigh != NULL */
747
        if (ipa_nonzero(gw))
748
            nbr = neigh_find2(&p->p, &gw, NULL, 0);
749
        else if (ipa_nonzero(ll))
750
            nbr = neigh_find2(&p->p, &ll, p->neigh->iface, 0);
750 751

  
751
    if (!nbr || (nbr->scope == SCOPE_HOST))
752
      WITHDRAW(BAD_NEXT_HOP);
752
        if (!nbr || (nbr->scope == SCOPE_HOST))
753
            WITHDRAW(BAD_NEXT_HOP);
753 754

  
754
    a->dest = RTD_UNICAST;
755
    a->nh.gw = nbr->addr;
756
    a->nh.iface = nbr->iface;
757
  }
758
  else /* GW_RECURSIVE */
759
  {
760
    if (ipa_zero(gw))
761
      WITHDRAW(BAD_NEXT_HOP);
755
        a->dest = RTD_UNICAST;
756
        a->nh.gw = nbr->addr;
757
        a->nh.iface = nbr->iface;
758
    }
759
    else /* GW_RECURSIVE */
760
    {
761
        if (ipa_zero(gw))
762
            WITHDRAW(BAD_NEXT_HOP);
762 763

  
763
    rtable *tab = ipa_is_ip4(gw) ? c->igp_table_ip4 : c->igp_table_ip6;
764
    s->hostentry = rt_get_hostentry(tab, gw, ll, c->c.table);
764
        rtable *tab = ipa_is_ip4(gw) ? c->igp_table_ip4 : c->igp_table_ip6;
765
        s->hostentry = rt_get_hostentry(tab, gw, ll, c->c.table);
765 766

  
766
    if (!s->mpls)
767
      rta_apply_hostentry(a, s->hostentry, NULL);
767
        if (!s->mpls)
768
            rta_apply_hostentry(a, s->hostentry, NULL);
768 769

  
769
    /* With MPLS, hostentry is applied later in bgp_apply_mpls_labels() */
770
  }
770
        /* With MPLS, hostentry is applied later in bgp_apply_mpls_labels() */
771
    }
771 772
}
772 773

  
773 774
static void
774 775
bgp_apply_mpls_labels(struct bgp_parse_state *s, rta *a, u32 *labels, uint lnum)
775 776
{
776
  if (lnum > MPLS_MAX_LABEL_STACK)
777
  {
778
    REPORT("Too many MPLS labels ($u)", lnum);
777
    if (lnum > MPLS_MAX_LABEL_STACK)
778
    {
779
        REPORT("Too many MPLS labels ($u)", lnum);
779 780

  
780
    a->dest = RTD_UNREACHABLE;
781
    a->hostentry = NULL;
782
    a->nh = (struct nexthop) { };
783
    return;
784
  }
781
        a->dest = RTD_UNREACHABLE;
782
        a->hostentry = NULL;
783
        a->nh = (struct nexthop) { };
784
        return;
785
    }
785 786

  
786
  /* Handle implicit NULL as empty MPLS stack */
787
  if ((lnum == 1) && (labels[0] == BGP_MPLS_NULL))
788
    lnum = 0;
787
    /* Handle implicit NULL as empty MPLS stack */
788
    if ((lnum == 1) && (labels[0] == BGP_MPLS_NULL))
789
        lnum = 0;
789 790

  
790
  if (s->channel->cf->gw_mode == GW_DIRECT)
791
  {
792
    a->nh.labels = lnum;
793
    memcpy(a->nh.label, labels, 4*lnum);
794
  }
795
  else /* GW_RECURSIVE */
796
  {
797
    mpls_label_stack ms;
791
    if (s->channel->cf->gw_mode == GW_DIRECT)
792
    {
793
        a->nh.labels = lnum;
794
        memcpy(a->nh.label, labels, 4*lnum);
795
    }
796
    else /* GW_RECURSIVE */
797
    {
798
        mpls_label_stack ms;
798 799

  
799
    ms.len = lnum;
800
    memcpy(ms.stack, labels, 4*lnum);
801
    rta_apply_hostentry(a, s->hostentry, &ms);
802
  }
800
        ms.len = lnum;
801
        memcpy(ms.stack, labels, 4*lnum);
802
        rta_apply_hostentry(a, s->hostentry, &ms);
803
    }
803 804
}
804 805

  
805 806

  
806 807
static inline int
807 808
bgp_use_next_hop(struct bgp_export_state *s, eattr *a)
808 809
{
809
  struct bgp_proto *p = s->proto;
810
  ip_addr *nh = (void *) a->u.ptr->data;
810
    struct bgp_proto *p = s->proto;
811
    ip_addr *nh = (void *) a->u.ptr->data;
811 812

  
812
  if (s->channel->cf->next_hop_self)
813
    return 0;
813
    if (s->channel->cf->next_hop_self)
814
        return 0;
814 815

  
815
  if (s->channel->cf->next_hop_keep)
816
    return 1;
816
    if (s->channel->cf->next_hop_keep)
817
        return 1;
817 818

  
818
  /* Keep it when explicitly set in export filter */
819
  if (a->type & EAF_FRESH)
820
    return 1;
819
    /* Keep it when explicitly set in export filter */
820
    if (a->type & EAF_FRESH)
821
        return 1;
821 822

  
822
  /* Keep it when exported to internal peers */
823
  if (p->is_interior && ipa_nonzero(*nh))
824
    return 1;
823
    /* Keep it when exported to internal peers */
824
    if (p->is_interior && ipa_nonzero(*nh))
825
        return 1;
825 826

  
826
  /* Keep it when forwarded between single-hop BGPs on the same iface */
827
  struct iface *ifa = (s->src && s->src->neigh) ? s->src->neigh->iface : NULL;
828
  return p->neigh && (p->neigh->iface == ifa);
827
    /* Keep it when forwarded between single-hop BGPs on the same iface */
828
    struct iface *ifa = (s->src && s->src->neigh) ? s->src->neigh->iface : NULL;
829
    return p->neigh && (p->neigh->iface == ifa);
829 830
}
830 831

  
831 832
static inline int
832 833
bgp_use_gateway(struct bgp_export_state *s)
833 834
{
834
  struct bgp_proto *p = s->proto;
835
  rta *ra = s->route->attrs;
835
    struct bgp_proto *p = s->proto;
836
    rta *ra = s->route->attrs;
836 837

  
837
  if (s->channel->cf->next_hop_self)
838
    return 0;
838
    if (s->channel->cf->next_hop_self)
839
        return 0;
839 840

  
840
  /* We need one valid global gateway */
841
  if ((ra->dest != RTD_UNICAST) || ra->nh.next || ipa_zero(ra->nh.gw) || ipa_is_link_local(ra->nh.gw))
842
    return 0;
841
    /* We need one valid global gateway */
842
    if ((ra->dest != RTD_UNICAST) || ra->nh.next || ipa_zero(ra->nh.gw) || ipa_is_link_local(ra->nh.gw))
843
        return 0;
843 844

  
844
  /* Use it when exported to internal peers */
845
  if (p->is_interior)
846
    return 1;
845
    /* Use it when exported to internal peers */
846
    if (p->is_interior)
847
        return 1;
847 848

  
848
  /* Use it when forwarded to single-hop BGP peer on on the same iface */
849
  return p->neigh && (p->neigh->iface == ra->nh.iface);
849
    /* Use it when forwarded to single-hop BGP peer on on the same iface */
850
    return p->neigh && (p->neigh->iface == ra->nh.iface);
850 851
}
851 852

  
852 853
static void
853 854
bgp_update_next_hop_ip(struct bgp_export_state *s, eattr *a, ea_list **to)
854 855
{
855
  if (!a || !bgp_use_next_hop(s, a))
856
  {
857
    if (bgp_use_gateway(s))
856
    if (!a || !bgp_use_next_hop(s, a))
858 857
    {
859
      rta *ra = s->route->attrs;
860
      ip_addr nh[1] = { ra->nh.gw };
861
      bgp_set_attr_data(to, s->pool, BA_NEXT_HOP, 0, nh, 16);
862

  
863
      if (s->mpls)
864
      {
865
	u32 implicit_null = BGP_MPLS_NULL;
866
	u32 *labels = ra->nh.labels ? ra->nh.label : &implicit_null;
867
	uint lnum = ra->nh.labels ? ra->nh.labels : 1;
868
	bgp_set_attr_data(to, s->pool, BA_MPLS_LABEL_STACK, 0, labels, lnum * 4);
869
      }
858
        if (bgp_use_gateway(s))
859
        {
860
            rta *ra = s->route->attrs;
861
            ip_addr nh[1] = { ra->nh.gw };
862
            bgp_set_attr_data(to, s->pool, BA_NEXT_HOP, 0, nh, 16);
863

  
864
            if (s->mpls)
865
            {
866
                u32 implicit_null = BGP_MPLS_NULL;
867
                u32 *labels = ra->nh.labels ? ra->nh.label : &implicit_null;
868
                uint lnum = ra->nh.labels ? ra->nh.labels : 1;
869
                bgp_set_attr_data(to, s->pool, BA_MPLS_LABEL_STACK, 0, labels, lnum * 4);
870
            }
871
        }
872
        else
873
        {
874
            ip_addr nh[2] = { s->channel->next_hop_addr, s->channel->link_addr };
875
            bgp_set_attr_data(to, s->pool, BA_NEXT_HOP, 0, nh, ipa_nonzero(nh[1]) ? 32 : 16);
876

  
877
            /* TODO: Use local MPLS assigned label */
878
            if (s->mpls)
879
                bgp_unset_attr(to, s->pool, BA_MPLS_LABEL_STACK);
880
        }
870 881
    }
871
    else
872
    {
873
      ip_addr nh[2] = { s->channel->next_hop_addr, s->channel->link_addr };
874
      bgp_set_attr_data(to, s->pool, BA_NEXT_HOP, 0, nh, ipa_nonzero(nh[1]) ? 32 : 16);
875 882

  
876
      /* TODO: Use local MPLS assigned label */
877
      if (s->mpls)
878
	bgp_unset_attr(to, s->pool, BA_MPLS_LABEL_STACK);
883
    /* Check if next hop is valid */
884
    a = bgp_find_attr(*to, BA_NEXT_HOP);
885
    if (!a)
886
        WITHDRAW(NO_NEXT_HOP);
887

  
888
    ip_addr *nh = (void *) a->u.ptr->data;
889
    ip_addr peer = s->proto->cf->remote_ip;
890
    uint len = a->u.ptr->length;
891

  
892
    /* Forbid zero next hop */
893
    if (ipa_zero(nh[0]) && ((len != 32) || ipa_zero(nh[1])))
894
        WITHDRAW(BAD_NEXT_HOP);
895

  
896
    //TODO prima le righe non erano commentate
897

  
898
    /* Forbid next hop equal to neighbor IP */
899
    //if (ipa_equal(peer, nh[0]) || ((len == 32) && ipa_equal(peer, nh[1])))
900
    //WITHDRAW(BAD_NEXT_HOP);
901
    //log(L_INFO "WITHDRAW CHECKER = %d", withdraw_checker);
902
    if(withdraw_checker != 0) {
903
        //log(L_INFO "IMPEDISCO LA RICONDIVISIONE DEL MESSAGGIO?");
904
        if (ipa_equal(peer, nh[0]) || ((len == 32) && ipa_equal(peer, nh[1]))) {
905
            //log(L_INFO "IMPEDIRE");
906
            WITHDRAW(BAD_NEXT_HOP);
907
        } else {
908
            //log(L_INFO "Non impedire");
909
        }
879 910
    }
880
  }
881

  
882
  /* Check if next hop is valid */
883
  a = bgp_find_attr(*to, BA_NEXT_HOP);
884
  if (!a)
885
    WITHDRAW(NO_NEXT_HOP);
886

  
887
  ip_addr *nh = (void *) a->u.ptr->data;
888
  ip_addr peer = s->proto->cf->remote_ip;
889
  uint len = a->u.ptr->length;
890

  
891
  /* Forbid zero next hop */
892
  if (ipa_zero(nh[0]) && ((len != 32) || ipa_zero(nh[1])))
893
    WITHDRAW(BAD_NEXT_HOP);
894 911

  
895
  /* Forbid next hop equal to neighbor IP */
896
  if (ipa_equal(peer, nh[0]) || ((len == 32) && ipa_equal(peer, nh[1])))
897
    WITHDRAW(BAD_NEXT_HOP);
912
    /* Forbid next hop with non-matching AF */
913
    if ((ipa_is_ip4(nh[0]) != bgp_channel_is_ipv4(s->channel)) &&
914
        !s->channel->ext_next_hop)
915
        WITHDRAW(BAD_NEXT_HOP);
898 916

  
899
  /* Forbid next hop with non-matching AF */
900
  if ((ipa_is_ip4(nh[0]) != bgp_channel_is_ipv4(s->channel)) &&
901
      !s->channel->ext_next_hop)
902
    WITHDRAW(BAD_NEXT_HOP);
903

  
904
  /* Just check if MPLS stack */
905
  if (s->mpls && !bgp_find_attr(*to, BA_MPLS_LABEL_STACK))
906
    WITHDRAW(NO_LABEL_STACK);
917
    /* Just check if MPLS stack */
918
    if (s->mpls && !bgp_find_attr(*to, BA_MPLS_LABEL_STACK))
919
        WITHDRAW(NO_LABEL_STACK);
907 920
}
908 921

  
909 922
static uint
910 923
bgp_encode_next_hop_ip(struct bgp_write_state *s, eattr *a, byte *buf, uint size UNUSED)
911 924
{
912
  /* This function is used only for MP-BGP, see bgp_encode_next_hop() for IPv4 BGP */
913
  ip_addr *nh = (void *) a->u.ptr->data;
914
  uint len = a->u.ptr->length;
925
    /* This function is used only for MP-BGP, see bgp_encode_next_hop() for IPv4 BGP */
926
    ip_addr *nh = (void *) a->u.ptr->data;
927
    uint len = a->u.ptr->length;
915 928

  
916
  ASSERT((len == 16) || (len == 32));
929
    ASSERT((len == 16) || (len == 32));
917 930

  
918
  /*
919
   * Both IPv4 and IPv6 next hops can be used (with ext_next_hop enabled). This
920
   * is specified in RFC 5549 for IPv4 and in RFC 4798 for IPv6. The difference
921
   * is that IPv4 address is directly encoded with IPv4 NLRI, but as IPv4-mapped
922
   * IPv6 address with IPv6 NLRI.
923
   */
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff