Statistics
| Branch: | Revision:

iof-bird / bird-2.0.1 / proto / bgp / packets.c @ 6b3f1a54

History | View | Annotate | Download (95 KB)

1
/*
2
 *        BIRD -- BGP Packet Processing
3
 *
4
 *        (c) 2000 Martin Mares <mj@ucw.cz>
5
 *        (c) 2008--2016 Ondrej Zajicek <santiago@crfreenet.org>
6
 *        (c) 2008--2016 CZ.NIC z.s.p.o.
7
 *
8
 *        Can be freely distributed and used under the terms of the GNU GPL.
9
 */
10

    
11
#undef LOCAL_DEBUG
12

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

    
16
#include "nest/bird.h"
17
#include "nest/iface.h"
18
#include "nest/protocol.h"
19
#include "nest/route.h"
20
#include "nest/attrs.h"
21
#include "nest/mrtdump.h"
22
#include "conf/conf.h"
23
#include "lib/unaligned.h"
24
#include "lib/flowspec.h"
25
#include "lib/socket.h"
26

    
27
#include "nest/cli.h"
28

    
29
#include "bgp.h"
30

    
31

    
32
#define BGP_RR_REQUEST                0
33
#define BGP_RR_BEGIN                1
34
#define BGP_RR_END                2
35

    
36
#define BGP_NLRI_MAX                (4 + 1 + 32)
37

    
38
#define BGP_MPLS_BOS                1        /* Bottom-of-stack bit */
39
#define BGP_MPLS_MAX                10        /* Max number of labels that 24*n <= 255 */
40
#define BGP_MPLS_NULL                3        /* Implicit NULL label */
41
#define BGP_MPLS_MAGIC                0x800000 /* Magic withdraw label value, RFC 3107 3 */
42

    
43

    
44
static struct tbf rl_rcv_update = TBF_DEFAULT_LOG_LIMITS;
45
static struct tbf rl_snd_update = TBF_DEFAULT_LOG_LIMITS;
46

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

    
54

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

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

    
64
    return NULL;
65
}
66

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

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

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

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

    
94
/*
95
 * MRT Dump format is not semantically specified.
96
 * We will use these values in appropriate fields:
97
 *
98
 * Local AS, Remote AS - configured AS numbers for given BGP instance.
99
 * Local IP, Remote IP - IP addresses of the TCP connection (0 if no connection)
100
 *
101
 * We dump two kinds of MRT messages: STATE_CHANGE (for BGP state
102
 * changes) and MESSAGE (for received BGP messages).
103
 *
104
 * STATE_CHANGE uses always AS4 variant, but MESSAGE uses AS4 variant
105
 * only when AS4 session is established and even in that case MESSAGE
106
 * does not use AS4 variant for initial OPEN message. This strange
107
 * behavior is here for compatibility with Quagga and Bgpdump,
108
 */
109

    
110
static byte *
111
mrt_put_bgp4_hdr(byte *buf, struct bgp_conn *conn, int as4)
112
{
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
    }
128

    
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;
132

    
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
    }
143

    
144
    return buf;
145
}
146

    
147
static void
148
mrt_dump_bgp_packet(struct bgp_conn *conn, byte *pkt, uint len)
149
{
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;
153

    
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);
159
}
160

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

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

    
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);
179
}
180

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

    
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;
191
}
192

    
193

    
194
/* Capability negotiation as per RFC 5492 */
195

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

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

    
205
    return NULL;
206
}
207

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

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

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

    
221
    return ac;
222
}
223

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

    
231

    
232
static byte *
233
bgp_write_capabilities(struct bgp_conn *conn, byte *buf)
234
{
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;
242

    
243
    /* Prepare bgp_caps structure */
244

    
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;
248

    
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;
256

    
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;
262
    }
263

    
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;
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;
273

    
274
        ac->add_path = c->cf->add_path;
275
        any_add_path |= ac->add_path;
276

    
277
        if (c->cf->gr_able)
278
        {
279
            ac->gr_able = 1;
280

    
281
            if (p->p.gr_recovery)
282
                ac->gr_af_flags |= BGP_GRF_FORWARDING;
283
        }
284
    }
285

    
286
    /* Sort capability fields by AFI/SAFI */
287
    qsort(caps->af_data, caps->af_count, sizeof(struct bgp_af_caps), bgp_af_caps_cmp);
288

    
289

    
290
    /* Create capability list in buffer */
291

    
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
     */
297

    
298
    WALK_AF_CAPS(caps, ac)
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
    }
312

    
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
    }
329

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

    
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;
389
}
390

    
391
static void
392
bgp_read_capabilities(struct bgp_conn *conn, struct bgp_caps *caps, byte *pos, int len)
393
{
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;
522
}
523

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

    
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));
534

    
535
    while (len > 0)
536
    {
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);
555
    }
556

    
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);
560

    
561
    return 0;
562
}
563

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

    
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);
571

    
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);
576

    
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);
582

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

    
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));
593

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

    
598
    return buf;
599
}
600

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

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

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

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

    
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);
623

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

    
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; }
633

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

    
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;
707

    
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);
710

    
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);
714
}
715

    
716

    
717
/*
718
 *        Next hop handling
719
 */
720

    
721
#define REPORT(msg, args...) \
722
  ({ log(L_REMOTE "%s: " msg, s->proto->p.name, ## args); })
723

    
724
#define DISCARD(msg, args...) \
725
  ({ REPORT(msg, ## args); return; })
726

    
727
#define WITHDRAW(msg, args...) \
728
  ({ REPORT(msg, ## args); s->err_withdraw = 1; return; })
729

    
730
#define BAD_AFI                "Unexpected AF <%u/%u> in UPDATE"
731
#define BAD_NEXT_HOP        "Invalid NEXT_HOP attribute"
732
#define NO_NEXT_HOP        "Missing NEXT_HOP attribute"
733
#define NO_LABEL_STACK        "Missing MPLS stack"
734

    
735

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

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

    
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);
751

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

    
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);
763

    
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);
766

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

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

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

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

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

    
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;
799

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

    
806

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

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

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

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

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

    
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);
830
}
831

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

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

    
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;
844

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

    
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);
851
}
852

    
853
static void
854
bgp_update_next_hop_ip(struct bgp_export_state *s, eattr *a, ea_list **to)
855
{
856
    if (!a || !bgp_use_next_hop(s, a))
857
    {
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
        }
881
    }
882

    
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
        }
910
    }
911

    
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);
916

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

    
922
static uint
923
bgp_encode_next_hop_ip(struct bgp_write_state *s, eattr *a, byte *buf, uint size UNUSED)
924
{
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;
928

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

    
931
    /*
932
     * Both IPv4 and IPv6 next hops can be used (with ext_next_hop enabled). This
933
     * is specified in RFC 5549 for IPv4 and in RFC 4798 for IPv6. The difference
934
     * is that IPv4 address is directly encoded with IPv4 NLRI, but as IPv4-mapped
935
     * IPv6 address with IPv6 NLRI.
936
     */
937

    
938
    if (bgp_channel_is_ipv4(s->channel) && ipa_is_ip4(nh[0]))
939
    {
940
        put_ip4(buf, ipa_to_ip4(nh[0]));
941
        return 4;
942
    }
943

    
944
    put_ip6(buf, ipa_to_ip6(nh[0]));
945

    
946
    if (len == 32)
947
        put_ip6(buf+16, ipa_to_ip6(nh[1]));
948

    
949
    return len;
950
}
951

    
952
static void
953
bgp_decode_next_hop_ip(struct bgp_parse_state *s, byte *data, uint len, rta *a)
954
{
955
    struct bgp_channel *c = s->channel;
956
    struct adata *ad = lp_alloc_adata(s->pool, 32);
957
    ip_addr *nh = (void *) ad->data;
958

    
959
    if (len == 4)
960
    {
961
        nh[0] = ipa_from_ip4(get_ip4(data));
962
        nh[1] = IPA_NONE;
963
    }
964
    else if (len == 16)
965
    {
966
        nh[0] = ipa_from_ip6(get_ip6(data));
967
        nh[1] = IPA_NONE;
968

    
969
        if (ipa_is_link_local(nh[0]))
970
        { nh[1] = nh[0]; nh[0] = IPA_NONE; }
971
    }
972
    else if (len == 32)
973
    {
974
        nh[0] = ipa_from_ip6(get_ip6(data));
975
        nh[1] = ipa_from_ip6(get_ip6(data+16));
976

    
977
        if (ipa_is_ip4(nh[0]) || !ip6_is_link_local(nh[1]))
978
            nh[1] = IPA_NONE;
979
    }
980
    else
981
        bgp_parse_error(s, 9);
982

    
983
    if (ipa_zero(nh[1]))
984
        ad->length = 16;
985

    
986
    if ((bgp_channel_is_ipv4(c) != ipa_is_ip4(nh[0])) && !c->ext_next_hop)
987
        WITHDRAW(BAD_NEXT_HOP);
988

    
989
    // XXXX validate next hop
990

    
991
    bgp_set_attr_ptr(&(a->eattrs), s->pool, BA_NEXT_HOP, 0, ad);
992
    bgp_apply_next_hop(s, a, nh[0], nh[1]);
993
}
994

    
995
static uint
996
bgp_encode_next_hop_vpn(struct bgp_write_state *s, eattr *a, byte *buf, uint size UNUSED)
997
{
998
    ip_addr *nh = (void *) a->u.ptr->data;
999
    uint len = a->u.ptr->length;
1000

    
1001
    ASSERT((len == 16) || (len == 32));
1002

    
1003
    /*
1004
     * Both IPv4 and IPv6 next hops can be used (with ext_next_hop enabled). This
1005
     * is specified in RFC 5549 for VPNv4 and in RFC 4659 for VPNv6. The difference
1006
     * is that IPv4 address is directly encoded with VPNv4 NLRI, but as IPv4-mapped
1007
     * IPv6 address with VPNv6 NLRI.
1008
     */
1009

    
1010
    if (bgp_channel_is_ipv4(s->channel) && ipa_is_ip4(nh[0]))
1011
    {
1012
        put_u64(buf, 0); /* VPN RD is 0 */
1013
        put_ip4(buf+8, ipa_to_ip4(nh[0]));
1014
        return 12;
1015
    }
1016

    
1017
    put_u64(buf, 0); /* VPN RD is 0 */
1018
    put_ip6(buf+8, ipa_to_ip6(nh[0]));
1019

    
1020
    if (len == 16)
1021
        return 24;
1022

    
1023
    put_u64(buf+24, 0); /* VPN RD is 0 */
1024
    put_ip6(buf+32, ipa_to_ip6(nh[1]));
1025

    
1026
    return 48;
1027
}
1028

    
1029
static void
1030
bgp_decode_next_hop_vpn(struct bgp_parse_state *s, byte *data, uint len, rta *a)
1031
{
1032
    struct bgp_channel *c = s->channel;
1033
    struct adata *ad = lp_alloc_adata(s->pool, 32);
1034
    ip_addr *nh = (void *) ad->data;
1035

    
1036
    if (len == 12)
1037
    {
1038
        nh[0] = ipa_from_ip4(get_ip4(data+8));
1039
        nh[1] = IPA_NONE;
1040
    }
1041
    else if (len == 24)
1042
    {
1043
        nh[0] = ipa_from_ip6(get_ip6(data+8));
1044
        nh[1] = IPA_NONE;
1045

    
1046
        if (ipa_is_link_local(nh[0]))
1047
        { nh[1] = nh[0]; nh[0] = IPA_NONE; }
1048
    }
1049
    else if (len == 48)
1050
    {
1051
        nh[0] = ipa_from_ip6(get_ip6(data+8));
1052
        nh[1] = ipa_from_ip6(get_ip6(data+32));
1053

    
1054
        if (ipa_is_ip4(nh[0]) || !ip6_is_link_local(nh[1]))
1055
            nh[1] = IPA_NONE;
1056
    }
1057
    else
1058
        bgp_parse_error(s, 9);
1059

    
1060
    if (ipa_zero(nh[1]))
1061
        ad->length = 16;
1062

    
1063
    /* XXXX which error */
1064
    if ((get_u64(data) != 0) || ((len == 48) && (get_u64(data+24) != 0)))
1065
        bgp_parse_error(s, 9);
1066

    
1067
    if ((bgp_channel_is_ipv4(c) != ipa_is_ip4(nh[0])) && !c->ext_next_hop)
1068
        WITHDRAW(BAD_NEXT_HOP);
1069

    
1070
    // XXXX validate next hop
1071

    
1072
    bgp_set_attr_ptr(&(a->eattrs), s->pool, BA_NEXT_HOP, 0, ad);
1073
    bgp_apply_next_hop(s, a, nh[0], nh[1]);
1074
}
1075

    
1076
/**
1077
 * USELESS FUNCTION??
1078
 * @param s
1079
 * @param a
1080
 * @param buf
1081
 * @param size
1082
 * @return
1083
 */
1084
static uint
1085
bgp_encode_next_hop_none(struct bgp_write_state *s UNUSED, eattr *a UNUSED, byte *buf UNUSED, uint size UNUSED)
1086
{
1087
    return 0;
1088
}
1089

    
1090
static void
1091
bgp_decode_next_hop_none(struct bgp_parse_state *s UNUSED, byte *data UNUSED, uint len UNUSED, rta *a UNUSED)
1092
{
1093
    /*
1094
     * Although we expect no next hop and RFC 7606 7.11 states that attribute
1095
     * MP_REACH_NLRI with unexpected next hop length is considered malformed,
1096
     * FlowSpec RFC 5575 4 states that next hop shall be ignored on receipt.
1097
     */
1098

    
1099
    return;
1100
}
1101

    
1102
static void
1103
bgp_update_next_hop_none(struct bgp_export_state *s, eattr *a, ea_list **to)
1104
{
1105
    /* NEXT_HOP shall not pass */
1106
    if (a)
1107
        bgp_unset_attr(to, s->pool, BA_NEXT_HOP);
1108
}
1109

    
1110

    
1111
/*
1112
 *        UPDATE
1113
 */
1114

    
1115
static void
1116
bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0)
1117
{
1118
    //log(L_INFO "BGP_RTE_UPDATE");
1119
    if (path_id != s->last_id)
1120
    {
1121
        s->last_src = rt_get_source(&s->proto->p, path_id);
1122
        s->last_id = path_id;
1123

    
1124
        rta_free(s->cached_rta);
1125
        s->cached_rta = NULL;
1126
    }
1127
    if (!a0)
1128
    {
1129
        rte_update2(&s->channel->c, n, NULL, s->last_src);
1130
        return;
1131
    }
1132
    /* Prepare cached route attributes */
1133
    if (s->cached_rta == NULL)
1134
    {
1135
        a0->src = s->last_src;
1136

    
1137
        /* Workaround for rta_lookup() breaking eattrs */
1138
        ea_list *ea = a0->eattrs;
1139
        s->cached_rta = rta_lookup(a0);
1140
        a0->eattrs = ea;
1141
    }
1142

    
1143
    rta *a = rta_clone(s->cached_rta);
1144
    rte *e = rte_get_temp(a);
1145
    e->pflags = 0;
1146
    e->u.bgp.suppressed = 0;
1147
    struct channel *c = &s->channel->c;
1148
    struct proto_stats *stats = &c->stats;
1149

    
1150
    //log(L_INFO "s->channel->c->stats->imp_updates_ignored: %d",stats->imp_updates_ignored);
1151
    //log(L_INFO "s->channel->c->stats->imp_routes: %d",stats->imp_routes);
1152
    //How much updates are ignored
1153
    uint old_imp_updates_ignored = stats->imp_updates_ignored;
1154
    rte_update2(&s->channel->c, n, e, s->last_src);
1155
    //log(L_INFO "s->channel->c->stats->imp_updates_ignored: %d",stats->imp_updates_ignored);
1156
    //log(L_INFO "s->channel->c->stats->imp_routes: %d",stats->imp_routes);
1157

    
1158
    //Check if the update was ignored by rte_update2
1159
    if(stats->imp_updates_ignored > old_imp_updates_ignored){
1160
        RTable *objFound = map_get(&RTmap, cKey);
1161
        const char *keyTmp;
1162
        map_iter_t iterator = map_iter(&objFound->NH);
1163
        int i = 0;
1164
        while ((keyTmp = map_next(&objFound->NH, &iterator))) {
1165
            i++;
1166
        }
1167
        if(i!=1)
1168
            updateNHmap(0);
1169
    }
1170

    
1171
    RTable *objFound = map_get(&RTmap, cKey);
1172
    if(objFound != NULL) {
1173
        //Set atributes of the route
1174
        if(objFound->primaVolta == 1) {
1175
            //log(L_INFO "Ho trovato primavolta == 1 dunque devo aggiornare i dati");
1176
            objFound->P = c->proto;
1177
            objFound->C = c;
1178
            objFound->n = net_get(c->table, n);
1179
            objFound->rtElem = e;
1180
            objFound->primaVolta = 0;
1181
        }
1182
    }
1183
}
1184

    
1185
static void
1186
bgp_encode_mpls_labels(struct bgp_write_state *s UNUSED, adata *mpls, byte **pos, uint *size, byte *pxlen)
1187
{
1188
    u32 dummy = 0;
1189
    u32 *labels = mpls ? (u32 *) mpls->data : &dummy;
1190
    uint lnum = mpls ? (mpls->length / 4) : 1;
1191

    
1192
    for (uint i = 0; i < lnum; i++)
1193
    {
1194
        put_u24(*pos, labels[i] << 4);
1195
        ADVANCE(*pos, *size, 3);
1196
    }
1197

    
1198
    /* Add bottom-of-stack flag */
1199
    (*pos)[-1] |= BGP_MPLS_BOS;
1200

    
1201
    *pxlen += 24 * lnum;
1202
}
1203

    
1204
static void
1205
bgp_decode_mpls_labels(struct bgp_parse_state *s, byte **pos, uint *len, uint *pxlen, rta *a)
1206
{
1207
    u32 labels[BGP_MPLS_MAX], label;
1208
    uint lnum = 0;
1209

    
1210
    do {
1211
        if (*pxlen < 24)
1212
            bgp_parse_error(s, 1);
1213

    
1214
        label = get_u24(*pos);
1215
        labels[lnum++] = label >> 4;
1216
        ADVANCE(*pos, *len, 3);
1217
        *pxlen -= 24;
1218

    
1219
        /* Withdraw: Magic label stack value 0x800000 according to RFC 3107, section 3, last paragraph */
1220
        if (!a && !s->err_withdraw && (lnum == 1) && (label == BGP_MPLS_MAGIC))
1221
            break;
1222
    }
1223
    while (!(label & BGP_MPLS_BOS));
1224

    
1225
    if (!a)
1226
        return;
1227

    
1228
    /* Attach MPLS attribute unless we already have one */
1229
    if (!s->mpls_labels)
1230
    {
1231
        s->mpls_labels = lp_alloc_adata(s->pool, 4*BGP_MPLS_MAX);
1232
        bgp_set_attr_ptr(&(a->eattrs), s->pool, BA_MPLS_LABEL_STACK, 0, s->mpls_labels);
1233
    }
1234

    
1235
    /* Overwrite data in the attribute */
1236
    s->mpls_labels->length = 4*lnum;
1237
    memcpy(s->mpls_labels->data, labels, 4*lnum);
1238

    
1239
    /* Update next hop entry in rta */
1240
    bgp_apply_mpls_labels(s, a, labels, lnum);
1241

    
1242
    /* Attributes were changed, invalidate cached entry */
1243
    rta_free(s->cached_rta);
1244
    s->cached_rta = NULL;
1245

    
1246
    return;
1247
}
1248

    
1249
/**
1250
 * Function used to encode a prexif in the knowledge of the AS inside the packet
1251
 * @param s state
1252
 * @param buck bucket where to get the prefix
1253
 * @param buf
1254
 * @param size
1255
 * @return
1256
 */
1257
static uint
1258
bgp_encode_nlri_ip4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
1259
{
1260
    byte *pos = buf;
1261

    
1262
    while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
1263
    {
1264
        struct bgp_prefix *px = HEAD(buck->prefixes);
1265
        struct net_addr_ip4 *net = (void *) px->net;
1266

    
1267
        /* Encode path ID */
1268
        if (s->add_path)
1269
        {
1270
            put_u32(pos, px->path_id);
1271
            ADVANCE(pos, size, 4);
1272
        }
1273

    
1274
        /* Encode prefix length */
1275
        *pos = net->pxlen;
1276
        ADVANCE(pos, size, 1);
1277

    
1278
        /* Encode MPLS labels */
1279
        if (s->mpls)
1280
            bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
1281

    
1282
        /* Encode prefix body */
1283
        ip4_addr a = ip4_hton(net->prefix);
1284
        uint b = (net->pxlen + 7) / 8;
1285
        memcpy(pos, &a, b);
1286
        ADVANCE(pos, size, b);
1287

    
1288
        bgp_free_prefix(s->channel, px);
1289
    }
1290

    
1291
    return pos - buf;
1292
}
1293

    
1294
/**
1295
 * Function to print in the log the actual state of the map
1296
 */
1297
void statoAttualeDellaMappa(){
1298
    char *jsonOut = malloc(sizeof(char) * 2);
1299
    strcpy(jsonOut, "");
1300
    char *tmpJsonOut = malloc(sizeof(char) * 150);
1301

    
1302
    const char *key;
1303
    char output[50];
1304
    map_iter_t iter;
1305
    iter = map_iter(&RTmap);
1306

    
1307
    while ((key = map_next(&RTmap, &iter))) {
1308
        sprintf(tmpJsonOut, "keyAddress: %s {\n",key);
1309
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1310
        strcat(jsonOut, tmpJsonOut);
1311

    
1312
        RTable *d = map_get(&RTmap, key);
1313

    
1314
        sprintf(tmpJsonOut, "\tInterno: %d,\n\tNH: {\n",d->interno);
1315
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1316
        strcat(jsonOut, tmpJsonOut);
1317

    
1318
        const char *internalKey;
1319
        map_iter_t internIter;
1320
        internIter = map_iter(&d->NH);
1321

    
1322
        while((internalKey = map_next(&d->NH, &internIter))){
1323
            int *nh = map_get(&d->NH, internalKey);
1324
            sprintf(tmpJsonOut, "\t\tkeyNH: %s,\n\t\tValue: %d\n",internalKey, *nh);
1325
            jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1326
            strcat(jsonOut, tmpJsonOut);
1327
        }
1328

    
1329
        sprintf(tmpJsonOut, "\t},\n\tLoadIn: {\n");
1330
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1331
        strcat(jsonOut, tmpJsonOut);
1332

    
1333
        internIter = map_iter(&d->loadin);
1334
        while ((internalKey = map_next(&d->loadin, &internIter))) {
1335
            float *loadIn = map_get(&d->loadin, internalKey);
1336
            snprintf(output, 50, "%f", *loadIn);
1337
            sprintf(tmpJsonOut, "\t\tkey: %s,\n\t\tloadIn: %s\n",internalKey,output);
1338
            jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1339
            strcat(jsonOut, tmpJsonOut);
1340
        }
1341

    
1342
        snprintf(output, 50, "%f", d->load);
1343
        sprintf(tmpJsonOut, "\t},\n\tLoad: %s\n", output);
1344
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1345
        strcat(jsonOut, tmpJsonOut);
1346
        sprintf(tmpJsonOut, "}\n");
1347
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1348
        strcat(jsonOut, tmpJsonOut);
1349
    }
1350

    
1351
    sprintf(tmpJsonOut, "AS_LOAD: {\n");
1352
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1353
    strcat(jsonOut, tmpJsonOut);
1354

    
1355
    iter = map_iter(&ASLoad_map);
1356
    while ((key = map_next(&ASLoad_map, &iter))) {
1357
        ASLoad *ASLoad_element = map_get(&ASLoad_map, key);
1358
        snprintf(output, 50, "%f", ASLoad_element->load);
1359
        sprintf(tmpJsonOut, "\tkey: %s, Load: %s, metrica: %d,\n",key,output,ASLoad_element->metrica);
1360
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1361
        strcat(jsonOut, tmpJsonOut);
1362
    }
1363
    sprintf(tmpJsonOut, "}\n");
1364
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1365
    strcat(jsonOut, tmpJsonOut);
1366

    
1367
    snprintf(output, 50, "%f", loadComplessivo);
1368
    sprintf(tmpJsonOut, "loadComplessivo: %s\n",output);
1369
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1370
    strcat(jsonOut, tmpJsonOut);
1371

    
1372
    snprintf(output, 50, "%d", total_number_of_update_sent);
1373
    sprintf(tmpJsonOut, "total_number_of_update_sent: %s\n",output);
1374
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1375
    strcat(jsonOut, tmpJsonOut);
1376

    
1377
    //The length of the log message is limited, so i have to split the map if the dimension is not enough
1378
    if(strlen(jsonOut) > 980){
1379
        char *jsonOutPartial = malloc(sizeof(char) * 981);
1380
        memcpy(jsonOutPartial, jsonOut, 980);
1381
        free(jsonOutPartial);
1382
    }
1383

    
1384
    log(L_INFO "\n%s",jsonOut);
1385
    free(tmpJsonOut);
1386
    free(jsonOut);
1387
}
1388

    
1389
/**
1390
 * Function to print the map into the log but with less informations
1391
 */
1392
void statoAttualeDellaMappaMinimal(){
1393
    char *jsonOut = malloc(sizeof(char) * 2);
1394
    char *tmpJsonOut = malloc(sizeof(char) * 150);
1395
    strcpy(jsonOut, "");
1396

    
1397
    char output[50];
1398
    const char *key;
1399
    map_iter_t iter;
1400

    
1401
    iter = map_iter(&ASLoad_map);
1402
    while ((key = map_next(&ASLoad_map, &iter))) {
1403
        ASLoad *ASLoad_element = map_get(&ASLoad_map, key);
1404
        snprintf(output, 50, "%f", ASLoad_element->load);
1405
        sprintf(tmpJsonOut, "\tkey: %s, Load: %s, metrica: %d;\n",key,output,ASLoad_element->metrica);
1406
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1407
        strcat(jsonOut, tmpJsonOut);
1408
    }
1409
    sprintf(tmpJsonOut, "}\n");
1410
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1411
    strcat(jsonOut, tmpJsonOut);
1412

    
1413
    snprintf(output, 50, "%f", loadComplessivo);
1414
    sprintf(tmpJsonOut, "loadComplessivo: %s,\n",output);
1415
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1416
    strcat(jsonOut, tmpJsonOut);
1417

    
1418
    snprintf(output, 50, "%d", total_number_of_update_sent);
1419
    sprintf(tmpJsonOut, "total_number_of_update_sent: %s,\n",output);
1420
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1421
    strcat(jsonOut, tmpJsonOut);
1422

    
1423
    int iterazioni = strlen(jsonOut) / 900;
1424
    if(strlen(jsonOut) % 900 > 0){
1425
        iterazioni++;
1426
    }
1427

    
1428
    //Split the message i more pieces
1429
    log(L_INFO "\nAS_LOAD: {");
1430
    char *jsonOutPartial;
1431
    char *pointerToJsonOutOriginal = jsonOut;
1432
    if(iterazioni > 1) {
1433
        jsonOutPartial = malloc(sizeof(char) * 901);
1434
        do {
1435
            memcpy(jsonOutPartial, jsonOut, 900);
1436
            jsonOut += 900;
1437
            jsonOutPartial[900] = '\0';
1438
            log(L_INFO "\n%s", jsonOutPartial);
1439
            memset(jsonOutPartial, 0, sizeof(*jsonOutPartial));
1440
        } while ((strlen(jsonOut) > 900));
1441
        if(strlen(jsonOut) > 0)
1442
            log(L_INFO "\n%s",jsonOut);
1443
        free(jsonOutPartial);
1444
    } else {
1445
        log(L_INFO "\n%s",jsonOut);
1446
    }
1447

    
1448
    log(L_INFO "\nIterazioni: %d", iterazioni);
1449
    jsonOut = NULL;
1450
    free(tmpJsonOut);
1451
    free(pointerToJsonOutOriginal);
1452
}
1453

    
1454
/**
1455
 * This is where the magic of DPC happen
1456
 * @param s
1457
 * @param pos
1458
 * @param len
1459
 * @param a
1460
 */
1461
static void
1462
bgp_decode_nlri_ip4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
1463
{
1464
    while (len)
1465
    {
1466
        net_addr_ip4 net;
1467
        u32 path_id = 0;
1468

    
1469
        /* Decode path ID */
1470
        if (s->add_path)
1471
        {
1472
            if (len < 5)
1473
                bgp_parse_error(s, 1);
1474

    
1475
            path_id = get_u32(pos);
1476
            ADVANCE(pos, len, 4);
1477
        }
1478

    
1479
        /* Decode prefix length */
1480
        uint l = *pos;
1481
        ADVANCE(pos, len, 1);
1482

    
1483
        if (len < ((l + 7) / 8))
1484
            bgp_parse_error(s, 1);
1485

    
1486
        /* Decode MPLS labels */
1487
        if (s->mpls)
1488
            bgp_decode_mpls_labels(s, &pos, &len, &l, a);
1489

    
1490
        if (l > IP4_MAX_PREFIX_LENGTH)
1491
            bgp_parse_error(s, 10);
1492

    
1493
        /* Decode prefix body */
1494
        ip4_addr addr = IP4_NONE;
1495
        uint b = (l + 7) / 8;
1496
        memcpy(&addr, pos, b);
1497
        ADVANCE(pos, len, b);
1498

    
1499
        net = NET_ADDR_IP4(ip4_ntoh(addr), l);
1500
        net_normalize_ip4(&net);
1501

    
1502
        // XXXX validate prefix
1503

    
1504
        net_addr *n = (net_addr *) &net;
1505

    
1506
        int keyAdr = n->data[0] + n->data[1] + n->data[2] + n->data[3];
1507
        char asCKey[12];
1508
        sprintf(cKey, "%d", keyAdr);
1509
        sprintf(nhCKey, "%d", nhKey);
1510
        sprintf(asCKey, "%d", ASRicezione);
1511

    
1512
        RTable *objFound;
1513
        map_iter_t iter;
1514
        const char *key;
1515
        int *NHmap;
1516
        //log(L_INFO "cKey: %s, nhCKey: %s, asCKey: %s", cKey, nhCKey, asCKey);
1517

    
1518
        if(withdraw_checker != 0){ //Withdraw section
1519
            //log(L_INFO "devo eliminare la voce con key: %s se il mio NH per la destinazione è colui che mi ha mandato il withdraw %s", cKey, asCKey);
1520
            objFound = map_get(&RTmap, cKey);
1521
            if (objFound) {
1522
                iter = map_iter(&objFound->NH);
1523
                while ((key = map_next(&objFound->NH, &iter))) {
1524
                    NHmap = map_get(&objFound->NH, key);
1525
                    if (*NHmap == ASRicezione) {
1526
                        map_remove(&RTmap, cKey);
1527
                    }
1528
                }
1529
            }
1530
        }
1531
        else {
1532
            NhVecchio = 0;
1533
            if(rilevatoLoop != 1){
1534
                // Nessun loop, controllo se la destinazione esiste già nella mappa
1535
                objFound = map_get(&RTmap, cKey);
1536
                if (objFound) {
1537
                    // Destinazione già presente nella mappa, aggiungo il nexthop alla lista dei nexthop
1538
                    NHmap = map_get(&objFound->NH, nhCKey);
1539
                    if (NHmap) {
1540
                        //log(L_INFO "NH già presente nella lista, lo lascio");
1541
                        NhVecchio = 1;
1542
                        objFound->primaVolta = 1;
1543
                    } else {
1544
                        //log(L_INFO "NH non trovato nella mappa, lo aggiungo");
1545
                        if(map_set(&objFound->NH, &nhCKey[0], ASRicezione) != 0){
1546
                            log(L_INFO "Elemento non aggiunto alla mappa, ERROR");
1547
                        }
1548
                    }
1549
                } else {
1550
                    //log(L_INFO "Destinazione non trovata, aggiungo la destinazione ed il nexthop alla mappa dei nexthop");
1551
                    RTable rtElem = initRTableElement(n,0,1);
1552
                    if(map_set(&RTmap, &cKey[0], rtElem) == 0){
1553
                        //log(L_INFO "Elemento aggiunto alla mappa");
1554
                        objFound = map_get(&RTmap, cKey);
1555
                        map_set(&ExternalDestinationMap, &cKey[0], 1);
1556
                        //log(L_INFO "Aggiungo il nh per questa nuova destinazione");
1557
                        if(map_set(&objFound->NH, &nhCKey[0], ASRicezione) != 0){
1558
                            log(L_INFO "Elemento non aggiunto alla mappa, ERROR");
1559
                        }
1560
                        objFound->primaVolta = 1;
1561
                    }
1562
                }
1563
            }
1564

    
1565
            /*Manage load contributes*/
1566
            char output[50];
1567
            if(sonoIlNH == 1){
1568
                //log(L_INFO "Io sono tra i NH del mittente, cKey: %s", cKey);
1569
                objFound = map_get(&RTmap, cKey);
1570
                if(objFound != NULL) {
1571
                    if (objFound->interno != 0) { //Se io sono origine e NH allora non aggiungo niente, non ho carico in ingresso per le mie stesse destinazioni
1572
                        float *LoadInmap = map_get(&objFound->loadin, asCKey);
1573
                        if (LoadInmap) {
1574
                            //snprintf(output, 50, "%f", loadOutRilevato);
1575
                            //log(L_INFO "Aggiorno il valore loadIn per questo NH, loadOutRilevato: %s NNH: %d", output, numeroNHarrivati);
1576
                            *LoadInmap = loadOutRilevato / (numeroNHarrivati * 1.0);
1577
                            //snprintf(output, 50, "%f", *LoadInmap);
1578
                            //log(L_INFO "Nuovo valore: %s", output);
1579
                        } else {
1580
                            //snprintf(output, 50, "%f", loadOutRilevato);
1581
                            //log(L_INFO "LoadIn non trovato nella mappa, lo aggiungo key: %s, loadOutRilevato: %s NNH: %d", nhCKey, output, numeroNHarrivati);
1582
                            float valoreLoadIn = loadOutRilevato / (numeroNHarrivati * 1.0);
1583
                            if (map_set(&objFound->loadin, &asCKey[0], valoreLoadIn) != 0) {
1584
                                snprintf(output, 50, "%f", valoreLoadIn);
1585
                                log(L_INFO "Elemento NON aggiunto alla mappa con valore: %s, ERROR", output);
1586
                            }
1587
                        }
1588
                    }
1589
                }
1590
            } else {
1591
                //log(L_INFO "Io NON sono tra i NH del mittente, rimuovo leventuale loadin");
1592
                objFound = map_get(&RTmap, cKey);
1593
                if(objFound != NULL) {
1594
                    map_remove(&objFound->loadin, asCKey);
1595
                }
1596
            }
1597
        }
1598

    
1599
        loadComplessivo = 0;
1600

    
1601
        // Load accumulation
1602
        iter = map_iter(&RTmap);
1603
        while ((key = map_next(&RTmap, &iter))) {
1604
            RTable *d = map_get(&RTmap, key);
1605
            if(d != NULL) {
1606
                const char *key4;
1607
                map_iter_t iter4 = map_iter(&d->loadin);
1608
                while ((key4 = map_next(&d->loadin, &iter4))) {
1609
                    float *loadIn = map_get(&d->loadin, key4);
1610
                    if (loadIn != NULL) {
1611
                        loadComplessivo += *loadIn;
1612
                    }
1613
                }
1614
            }
1615
        }
1616

    
1617
        //Repropagation information
1618
        ASLoad *ASLoad_element = map_get(&ASLoad_map, ASLocale);
1619
        if (ASLoad_element) {
1620
            if (ASLoad_element->load != loadComplessivo) { // The local AS have some new metrics to annunce
1621
                ASLoad_element->load = loadComplessivo;
1622
                ASLoad_element->metrica += 1;
1623

    
1624
                map_iter_t iter = map_iter(&ASLoad_element->remoteMap);
1625
                while ((key = map_next(&ASLoad_element->remoteMap, &iter))) {
1626
                    map_remove(&ASLoad_element->remoteMap, key);
1627
                }
1628
            }
1629
        }
1630

    
1631
        statoAttualeDellaMappaMinimal();
1632
        bgp_rte_update(s, (net_addr *) &net, path_id, a); //call to the function that update the RT
1633
    }
1634
}
1635

    
1636

    
1637
//TODO do it for ipv6? :thinking:
1638
static uint
1639
bgp_encode_nlri_ip6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
1640
{
1641
    byte *pos = buf;
1642

    
1643
    while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
1644
    {
1645
        struct bgp_prefix *px = HEAD(buck->prefixes);
1646
        struct net_addr_ip6 *net = (void *) px->net;
1647

    
1648
        /* Encode path ID */
1649
        if (s->add_path)
1650
        {
1651
            put_u32(pos, px->path_id);
1652
            ADVANCE(pos, size, 4);
1653
        }
1654

    
1655
        /* Encode prefix length */
1656
        *pos = net->pxlen;
1657
        ADVANCE(pos, size, 1);
1658

    
1659
        /* Encode MPLS labels */
1660
        if (s->mpls)
1661
            bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
1662

    
1663
        /* Encode prefix body */
1664
        ip6_addr a = ip6_hton(net->prefix);
1665
        uint b = (net->pxlen + 7) / 8;
1666
        memcpy(pos, &a, b);
1667
        ADVANCE(pos, size, b);
1668

    
1669
        bgp_free_prefix(s->channel, px);
1670
    }
1671

    
1672
    return pos - buf;
1673
}
1674

    
1675
static void
1676
bgp_decode_nlri_ip6(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
1677
{
1678
    while (len)
1679
    {
1680
        net_addr_ip6 net;
1681
        u32 path_id = 0;
1682

    
1683
        /* Decode path ID */
1684
        if (s->add_path)
1685
        {
1686
            if (len < 5)
1687
                bgp_parse_error(s, 1);
1688

    
1689
            path_id = get_u32(pos);
1690
            ADVANCE(pos, len, 4);
1691
        }
1692

    
1693
        /* Decode prefix length */
1694
        uint l = *pos;
1695
        ADVANCE(pos, len, 1);
1696

    
1697
        if (len < ((l + 7) / 8))
1698
            bgp_parse_error(s, 1);
1699

    
1700
        /* Decode MPLS labels */
1701
        if (s->mpls)
1702
            bgp_decode_mpls_labels(s, &pos, &len, &l, a);
1703

    
1704
        if (l > IP6_MAX_PREFIX_LENGTH)
1705
            bgp_parse_error(s, 10);
1706

    
1707
        /* Decode prefix body */
1708
        ip6_addr addr = IP6_NONE;
1709
        uint b = (l + 7) / 8;
1710
        memcpy(&addr, pos, b);
1711
        ADVANCE(pos, len, b);
1712

    
1713
        net = NET_ADDR_IP6(ip6_ntoh(addr), l);
1714
        net_normalize_ip6(&net);
1715

    
1716
        // XXXX validate prefix
1717

    
1718
        bgp_rte_update(s, (net_addr *) &net, path_id, a);
1719
    }
1720
}
1721

    
1722
static uint
1723
bgp_encode_nlri_vpn4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
1724
{
1725
    byte *pos = buf;
1726

    
1727
    while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
1728
    {
1729
        struct bgp_prefix *px = HEAD(buck->prefixes);
1730
        struct net_addr_vpn4 *net = (void *) px->net;
1731

    
1732
        /* Encode path ID */
1733
        if (s->add_path)
1734
        {
1735
            put_u32(pos, px->path_id);
1736
            ADVANCE(pos, size, 4);
1737
        }
1738

    
1739
        /* Encode prefix length */
1740
        *pos = 64 + net->pxlen;
1741
        ADVANCE(pos, size, 1);
1742

    
1743
        /* Encode MPLS labels */
1744
        if (s->mpls)
1745
            bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
1746

    
1747
        /* Encode route distinguisher */
1748
        put_u64(pos, net->rd);
1749
        ADVANCE(pos, size, 8);
1750

    
1751
        /* Encode prefix body */
1752
        ip4_addr a = ip4_hton(net->prefix);
1753
        uint b = (net->pxlen + 7) / 8;
1754
        memcpy(pos, &a, b);
1755
        ADVANCE(pos, size, b);
1756

    
1757
        bgp_free_prefix(s->channel, px);
1758
    }
1759

    
1760
    return pos - buf;
1761
}
1762

    
1763
static void
1764
bgp_decode_nlri_vpn4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
1765
{
1766
    while (len)
1767
    {
1768
        net_addr_vpn4 net;
1769
        u32 path_id = 0;
1770

    
1771
        /* Decode path ID */
1772
        if (s->add_path)
1773
        {
1774
            if (len < 5)
1775
                bgp_parse_error(s, 1);
1776

    
1777
            path_id = get_u32(pos);
1778
            ADVANCE(pos, len, 4);
1779
        }
1780

    
1781
        /* Decode prefix length */
1782
        uint l = *pos;
1783
        ADVANCE(pos, len, 1);
1784

    
1785
        if (len < ((l + 7) / 8))
1786
            bgp_parse_error(s, 1);
1787

    
1788
        /* Decode MPLS labels */
1789
        if (s->mpls)
1790
            bgp_decode_mpls_labels(s, &pos, &len, &l, a);
1791

    
1792
        /* Decode route distinguisher */
1793
        if (l < 64)
1794
            bgp_parse_error(s, 1);
1795

    
1796
        u64 rd = get_u64(pos);
1797
        ADVANCE(pos, len, 8);
1798
        l -= 64;
1799

    
1800
        if (l > IP4_MAX_PREFIX_LENGTH)
1801
            bgp_parse_error(s, 10);
1802

    
1803
        /* Decode prefix body */
1804
        ip4_addr addr = IP4_NONE;
1805
        uint b = (l + 7) / 8;
1806
        memcpy(&addr, pos, b);
1807
        ADVANCE(pos, len, b);
1808

    
1809
        net = NET_ADDR_VPN4(ip4_ntoh(addr), l, rd);
1810
        net_normalize_vpn4(&net);
1811

    
1812
        // XXXX validate prefix
1813

    
1814
        bgp_rte_update(s, (net_addr *) &net, path_id, a);
1815
    }
1816
}
1817

    
1818
static uint
1819
bgp_encode_nlri_vpn6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
1820
{
1821
    byte *pos = buf;
1822

    
1823
    while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
1824
    {
1825
        struct bgp_prefix *px = HEAD(buck->prefixes);
1826
        struct net_addr_vpn6 *net = (void *) px->net;
1827

    
1828
        /* Encode path ID */
1829
        if (s->add_path)
1830
        {
1831
            put_u32(pos, px->path_id);
1832
            ADVANCE(pos, size, 4);
1833
        }
1834

    
1835
        /* Encode prefix length */
1836
        *pos = 64 + net->pxlen;
1837
        ADVANCE(pos, size, 1);
1838

    
1839
        /* Encode MPLS labels */
1840
        if (s->mpls)
1841
            bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
1842

    
1843
        /* Encode route distinguisher */
1844
        put_u64(pos, net->rd);
1845
        ADVANCE(pos, size, 8);
1846

    
1847
        /* Encode prefix body */
1848
        ip6_addr a = ip6_hton(net->prefix);
1849
        uint b = (net->pxlen + 7) / 8;
1850
        memcpy(pos, &a, b);
1851
        ADVANCE(pos, size, b);
1852

    
1853
        bgp_free_prefix(s->channel, px);
1854
    }
1855

    
1856
    return pos - buf;
1857
}
1858

    
1859
static void
1860
bgp_decode_nlri_vpn6(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
1861
{
1862
    while (len)
1863
    {
1864
        net_addr_vpn6 net;
1865
        u32 path_id = 0;
1866

    
1867
        /* Decode path ID */
1868
        if (s->add_path)
1869
        {
1870
            if (len < 5)
1871
                bgp_parse_error(s, 1);
1872

    
1873
            path_id = get_u32(pos);
1874
            ADVANCE(pos, len, 4);
1875
        }
1876

    
1877
        /* Decode prefix length */
1878
        uint l = *pos;
1879
        ADVANCE(pos, len, 1);
1880

    
1881
        if (len < ((l + 7) / 8))
1882
            bgp_parse_error(s, 1);
1883

    
1884
        /* Decode MPLS labels */
1885
        if (s->mpls)
1886
            bgp_decode_mpls_labels(s, &pos, &len, &l, a);
1887

    
1888
        /* Decode route distinguisher */
1889
        if (l < 64)
1890
            bgp_parse_error(s, 1);
1891

    
1892
        u64 rd = get_u64(pos);
1893
        ADVANCE(pos, len, 8);
1894
        l -= 64;
1895

    
1896
        if (l > IP6_MAX_PREFIX_LENGTH)
1897
            bgp_parse_error(s, 10);
1898

    
1899
        /* Decode prefix body */
1900
        ip6_addr addr = IP6_NONE;
1901
        uint b = (l + 7) / 8;
1902
        memcpy(&addr, pos, b);
1903
        ADVANCE(pos, len, b);
1904

    
1905
        net = NET_ADDR_VPN6(ip6_ntoh(addr), l, rd);
1906
        net_normalize_vpn6(&net);
1907

    
1908
        // XXXX validate prefix
1909

    
1910
        bgp_rte_update(s, (net_addr *) &net, path_id, a);
1911
    }
1912
}
1913

    
1914
static uint
1915
bgp_encode_nlri_flow4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
1916
{
1917
    byte *pos = buf;
1918

    
1919
    while (!EMPTY_LIST(buck->prefixes) && (size >= 4))
1920
    {
1921
        struct bgp_prefix *px = HEAD(buck->prefixes);
1922
        struct net_addr_flow4 *net = (void *) px->net;
1923
        uint flen = net->length - sizeof(net_addr_flow4);
1924

    
1925
        /* Encode path ID */
1926
        if (s->add_path)
1927
        {
1928
            put_u32(pos, px->path_id);
1929
            ADVANCE(pos, size, 4);
1930
        }
1931

    
1932
        if (flen > size)
1933
            break;
1934

    
1935
        /* Copy whole flow data including length */
1936
        memcpy(pos, net->data, flen);
1937
        ADVANCE(pos, size, flen);
1938

    
1939
        bgp_free_prefix(s->channel, px);
1940
    }
1941

    
1942
    return pos - buf;
1943
}
1944

    
1945
static void
1946
bgp_decode_nlri_flow4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
1947
{
1948
    while (len)
1949
    {
1950
        u32 path_id = 0;
1951

    
1952
        /* Decode path ID */
1953
        if (s->add_path)
1954
        {
1955
            if (len < 4)
1956
                bgp_parse_error(s, 1);
1957

    
1958
            path_id = get_u32(pos);
1959
            ADVANCE(pos, len, 4);
1960
        }
1961

    
1962
        if (len < 2)
1963
            bgp_parse_error(s, 1);
1964

    
1965
        /* Decode flow length */
1966
        uint hlen = flow_hdr_length(pos);
1967
        uint dlen = flow_read_length(pos);
1968
        uint flen = hlen + dlen;
1969
        byte *data = pos + hlen;
1970

    
1971
        if (len < flen)
1972
            bgp_parse_error(s, 1);
1973

    
1974
        /* Validate flow data */
1975
        enum flow_validated_state r = flow4_validate(data, dlen);
1976
        if (r != FLOW_ST_VALID)
1977
        {
1978
            log(L_REMOTE "%s: Invalid flow route: %s", s->proto->p.name, flow_validated_state_str(r));
1979
            bgp_parse_error(s, 1);
1980
        }
1981

    
1982
        if (data[0] != FLOW_TYPE_DST_PREFIX)
1983
        {
1984
            log(L_REMOTE "%s: No dst prefix at first pos", s->proto->p.name);
1985
            bgp_parse_error(s, 1);
1986
        }
1987

    
1988
        /* Decode dst prefix */
1989
        ip4_addr px = IP4_NONE;
1990
        uint pxlen = data[1];
1991

    
1992
        // FIXME: Use some generic function
1993
        memcpy(&px, data+2, BYTES(pxlen));
1994
        px = ip4_and(ip4_ntoh(px), ip4_mkmask(pxlen));
1995

    
1996
        /* Prepare the flow */
1997
        net_addr *n = alloca(sizeof(struct net_addr_flow4) + flen);
1998
        net_fill_flow4(n, px, pxlen, pos, flen);
1999
        ADVANCE(pos, len, flen);
2000

    
2001
        bgp_rte_update(s, n, path_id, a);
2002
    }
2003
}
2004

    
2005
static uint
2006
bgp_encode_nlri_flow6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
2007
{
2008
    byte *pos = buf;
2009

    
2010
    while (!EMPTY_LIST(buck->prefixes) && (size >= 4))
2011
    {
2012
        struct bgp_prefix *px = HEAD(buck->prefixes);
2013
        struct net_addr_flow6 *net = (void *) px->net;
2014
        uint flen = net->length - sizeof(net_addr_flow6);
2015

    
2016
        /* Encode path ID */
2017
        if (s->add_path)
2018
        {
2019
            put_u32(pos, px->path_id);
2020
            ADVANCE(pos, size, 4);
2021
        }
2022

    
2023
        if (flen > size)
2024
            break;
2025

    
2026
        /* Copy whole flow data including length */
2027
        memcpy(pos, net->data, flen);
2028
        ADVANCE(pos, size, flen);
2029

    
2030
        bgp_free_prefix(s->channel, px);
2031
    }
2032

    
2033
    return pos - buf;
2034
}
2035

    
2036
static void
2037
bgp_decode_nlri_flow6(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
2038
{
2039
    while (len)
2040
    {
2041
        u32 path_id = 0;
2042

    
2043
        /* Decode path ID */
2044
        if (s->add_path)
2045
        {
2046
            if (len < 4)
2047
                bgp_parse_error(s, 1);
2048

    
2049
            path_id = get_u32(pos);
2050
            ADVANCE(pos, len, 4);
2051
        }
2052

    
2053
        if (len < 2)
2054
            bgp_parse_error(s, 1);
2055

    
2056
        /* Decode flow length */
2057
        uint hlen = flow_hdr_length(pos);
2058
        uint dlen = flow_read_length(pos);
2059
        uint flen = hlen + dlen;
2060
        byte *data = pos + hlen;
2061

    
2062
        if (len < flen)
2063
            bgp_parse_error(s, 1);
2064

    
2065
        /* Validate flow data */
2066
        enum flow_validated_state r = flow6_validate(data, dlen);
2067
        if (r != FLOW_ST_VALID)
2068
        {
2069
            log(L_REMOTE "%s: Invalid flow route: %s", s->proto->p.name, flow_validated_state_str(r));
2070
            bgp_parse_error(s, 1);
2071
        }
2072

    
2073
        if (data[0] != FLOW_TYPE_DST_PREFIX)
2074
        {
2075
            log(L_REMOTE "%s: No dst prefix at first pos", s->proto->p.name);
2076
            bgp_parse_error(s, 1);
2077
        }
2078

    
2079
        /* Decode dst prefix */
2080
        ip6_addr px = IP6_NONE;
2081
        uint pxlen = data[1];
2082

    
2083
        // FIXME: Use some generic function
2084
        memcpy(&px, data+2, BYTES(pxlen));
2085
        px = ip6_and(ip6_ntoh(px), ip6_mkmask(pxlen));
2086

    
2087
        /* Prepare the flow */
2088
        net_addr *n = alloca(sizeof(struct net_addr_flow6) + flen);
2089
        net_fill_flow6(n, px, pxlen, pos, flen);
2090
        ADVANCE(pos, len, flen);
2091

    
2092
        bgp_rte_update(s, n, path_id, a);
2093
    }
2094
}
2095

    
2096
//This data structure define what function to use, it's used by external libraries
2097
static const struct bgp_af_desc bgp_af_table[] = {
2098
        {
2099
                .afi = BGP_AF_IPV4,
2100
                .net = NET_IP4,
2101
                .name = "ipv4",
2102
                .encode_nlri = bgp_encode_nlri_ip4,
2103
                .decode_nlri = bgp_decode_nlri_ip4,
2104
                .encode_next_hop = bgp_encode_next_hop_ip,
2105
                .decode_next_hop = bgp_decode_next_hop_ip,
2106
                .update_next_hop = bgp_update_next_hop_ip,
2107
        },
2108
        {
2109
                .afi = BGP_AF_IPV4_MC,
2110
                .net = NET_IP4,
2111
                .name = "ipv4-mc",
2112
                .encode_nlri = bgp_encode_nlri_ip4,
2113
                .decode_nlri = bgp_decode_nlri_ip4,
2114
                .encode_next_hop = bgp_encode_next_hop_ip,
2115
                .decode_next_hop = bgp_decode_next_hop_ip,
2116
                .update_next_hop = bgp_update_next_hop_ip,
2117
        },
2118
        {
2119
                .afi = BGP_AF_IPV4_MPLS,
2120
                .net = NET_IP4,
2121
                .mpls = 1,
2122
                .name = "ipv4-mpls",
2123
                .encode_nlri = bgp_encode_nlri_ip4,
2124
                .decode_nlri = bgp_decode_nlri_ip4,
2125
                .encode_next_hop = bgp_encode_next_hop_ip,
2126
                .decode_next_hop = bgp_decode_next_hop_ip,
2127
                .update_next_hop = bgp_update_next_hop_ip,
2128
        },
2129
        {
2130
                .afi = BGP_AF_IPV6,
2131
                .net = NET_IP6,
2132
                .name = "ipv6",
2133
                .encode_nlri = bgp_encode_nlri_ip6,
2134
                .decode_nlri = bgp_decode_nlri_ip6,
2135
                .encode_next_hop = bgp_encode_next_hop_ip,
2136
                .decode_next_hop = bgp_decode_next_hop_ip,
2137
                .update_next_hop = bgp_update_next_hop_ip,
2138
        },
2139
        {
2140
                .afi = BGP_AF_IPV6_MC,
2141
                .net = NET_IP6,
2142
                .name = "ipv6-mc",
2143
                .encode_nlri = bgp_encode_nlri_ip6,
2144
                .decode_nlri = bgp_decode_nlri_ip6,
2145
                .encode_next_hop = bgp_encode_next_hop_ip,
2146
                .decode_next_hop = bgp_decode_next_hop_ip,
2147
                .update_next_hop = bgp_update_next_hop_ip,
2148
        },
2149
        {
2150
                .afi = BGP_AF_IPV6_MPLS,
2151
                .net = NET_IP6,
2152
                .mpls = 1,
2153
                .name = "ipv6-mpls",
2154
                .encode_nlri = bgp_encode_nlri_ip6,
2155
                .decode_nlri = bgp_decode_nlri_ip6,
2156
                .encode_next_hop = bgp_encode_next_hop_ip,
2157
                .decode_next_hop = bgp_decode_next_hop_ip,
2158
                .update_next_hop = bgp_update_next_hop_ip,
2159
        },
2160
        {
2161
                .afi = BGP_AF_VPN4_MPLS,
2162
                .net = NET_VPN4,
2163
                .mpls = 1,
2164
                .name = "vpn4-mpls",
2165
                .encode_nlri = bgp_encode_nlri_vpn4,
2166
                .decode_nlri = bgp_decode_nlri_vpn4,
2167
                .encode_next_hop = bgp_encode_next_hop_vpn,
2168
                .decode_next_hop = bgp_decode_next_hop_vpn,
2169
                .update_next_hop = bgp_update_next_hop_ip,
2170
        },
2171
        {
2172
                .afi = BGP_AF_VPN6_MPLS,
2173
                .net = NET_VPN6,
2174
                .mpls = 1,
2175
                .name = "vpn6-mpls",
2176
                .encode_nlri = bgp_encode_nlri_vpn6,
2177
                .decode_nlri = bgp_decode_nlri_vpn6,
2178
                .encode_next_hop = bgp_encode_next_hop_vpn,
2179
                .decode_next_hop = bgp_decode_next_hop_vpn,
2180
                .update_next_hop = bgp_update_next_hop_ip,
2181
        },
2182
        {
2183
                .afi = BGP_AF_VPN4_MC,
2184
                .net = NET_VPN4,
2185
                .name = "vpn4-mc",
2186
                .encode_nlri = bgp_encode_nlri_vpn4,
2187
                .decode_nlri = bgp_decode_nlri_vpn4,
2188
                .encode_next_hop = bgp_encode_next_hop_vpn,
2189
                .decode_next_hop = bgp_decode_next_hop_vpn,
2190
                .update_next_hop = bgp_update_next_hop_ip,
2191
        },
2192
        {
2193
                .afi = BGP_AF_VPN6_MC,
2194
                .net = NET_VPN6,
2195
                .name = "vpn6-mc",
2196
                .encode_nlri = bgp_encode_nlri_vpn6,
2197
                .decode_nlri = bgp_decode_nlri_vpn6,
2198
                .encode_next_hop = bgp_encode_next_hop_vpn,
2199
                .decode_next_hop = bgp_decode_next_hop_vpn,
2200
                .update_next_hop = bgp_update_next_hop_ip,
2201
        },
2202
        {
2203
                .afi = BGP_AF_FLOW4,
2204
                .net = NET_FLOW4,
2205
                .no_igp = 1,
2206
                .name = "flow4",
2207
                .encode_nlri = bgp_encode_nlri_flow4,
2208
                .decode_nlri = bgp_decode_nlri_flow4,
2209
                .encode_next_hop = bgp_encode_next_hop_none,
2210
                .decode_next_hop = bgp_decode_next_hop_none,
2211
                .update_next_hop = bgp_update_next_hop_none,
2212
        },
2213
        {
2214
                .afi = BGP_AF_FLOW6,
2215
                .net = NET_FLOW6,
2216
                .no_igp = 1,
2217
                .name = "flow6",
2218
                .encode_nlri = bgp_encode_nlri_flow6,
2219
                .decode_nlri = bgp_decode_nlri_flow6,
2220
                .encode_next_hop = bgp_encode_next_hop_none,
2221
                .decode_next_hop = bgp_decode_next_hop_none,
2222
                .update_next_hop = bgp_update_next_hop_none,
2223
        },
2224
};
2225

    
2226
const struct bgp_af_desc *
2227
bgp_get_af_desc(u32 afi)
2228
{
2229
    uint i;
2230
    for (i = 0; i < ARRAY_SIZE(bgp_af_table); i++)
2231
        if (bgp_af_table[i].afi == afi)
2232
            return &bgp_af_table[i];
2233

    
2234
    return NULL;
2235
}
2236

    
2237
static inline uint
2238
bgp_encode_nlri(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2239
{
2240
    return s->channel->desc->encode_nlri(s, buck, buf, end - buf);
2241
}
2242

    
2243
static inline uint
2244
bgp_encode_next_hop(struct bgp_write_state *s, eattr *nh, byte *buf)
2245
{
2246
    return s->channel->desc->encode_next_hop(s, nh, buf, 255);
2247
}
2248

    
2249
void
2250
bgp_update_next_hop(struct bgp_export_state *s, eattr *a, ea_list **to)
2251
{
2252
    s->channel->desc->update_next_hop(s, a, to);
2253
}
2254

    
2255
#define MAX_ATTRS_LENGTH (end-buf+BGP_HEADER_LENGTH - 1024)
2256

    
2257
/**
2258
 * For updates with new reachability info
2259
 * @param s
2260
 * @param buck
2261
 * @param buf
2262
 * @param end
2263
 * @return
2264
 */
2265
static byte *
2266
bgp_create_ip_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2267
{
2268
    /*
2269
     *        2 B        Withdrawn Routes Length (zero)
2270
     *        ---        IPv4 Withdrawn Routes NLRI (unused)
2271
     *        2 B        Total Path Attribute Length
2272
     *        var        Path Attributes
2273
     *        var        IPv4 Network Layer Reachability Information
2274
     */
2275

    
2276
    int lr, la;
2277

    
2278
    la = bgp_encode_attrs(s, buck->eattrs, buf+4, buf + MAX_ATTRS_LENGTH);
2279
    if (la < 0)
2280
    {
2281
        /* Attribute list too long */
2282
        bgp_withdraw_bucket(s->channel, buck);
2283
        return NULL;
2284
    }
2285

    
2286
    put_u16(buf+0, 0);
2287
    put_u16(buf+2, la);
2288

    
2289
    lr = bgp_encode_nlri(s, buck, buf+4+la, end);
2290

    
2291
    return buf+4+la+lr;
2292
}
2293

    
2294
static byte *
2295
bgp_create_mp_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2296
{
2297
    /*
2298
     *        2 B        IPv4 Withdrawn Routes Length (zero)
2299
     *        ---        IPv4 Withdrawn Routes NLRI (unused)
2300
     *        2 B        Total Path Attribute Length
2301
     *        1 B        MP_REACH_NLRI hdr - Attribute Flags
2302
     *        1 B        MP_REACH_NLRI hdr - Attribute Type Code
2303
     *        2 B        MP_REACH_NLRI hdr - Length of Attribute Data
2304
     *        2 B        MP_REACH_NLRI data - Address Family Identifier
2305
     *        1 B        MP_REACH_NLRI data - Subsequent Address Family Identifier
2306
     *        1 B        MP_REACH_NLRI data - Length of Next Hop Network Address
2307
     *        var        MP_REACH_NLRI data - Network Address of Next Hop
2308
     *        1 B        MP_REACH_NLRI data - Reserved (zero)
2309
     *        var        MP_REACH_NLRI data - Network Layer Reachability Information
2310
     *        var        Rest of Path Attributes
2311
     *        ---        IPv4 Network Layer Reachability Information (unused)
2312
     */
2313

    
2314
    int lh, lr, la;        /* Lengths of next hop, NLRI and attributes */
2315

    
2316
    /* Begin of MP_REACH_NLRI atribute */
2317
    buf[4] = BAF_OPTIONAL | BAF_EXT_LEN;
2318
    buf[5] = BA_MP_REACH_NLRI;
2319
    put_u16(buf+6, 0);                /* Will be fixed later */
2320
    put_af3(buf+8, s->channel->afi);
2321
    byte *pos = buf+11;
2322

    
2323
    /* Encode attributes to temporary buffer */
2324
    byte *abuf = alloca(MAX_ATTRS_LENGTH);
2325
    la = bgp_encode_attrs(s, buck->eattrs, abuf, abuf + MAX_ATTRS_LENGTH);
2326
    if (la < 0)
2327
    {
2328
        /* Attribute list too long */
2329
        bgp_withdraw_bucket(s->channel, buck);
2330
        return NULL;
2331
    }
2332

    
2333
    /* Encode the next hop */
2334
    lh = bgp_encode_next_hop(s, s->mp_next_hop, pos+1);
2335
    *pos = lh;
2336
    pos += 1+lh;
2337

    
2338
net_addr *n;
2339
    /* Reserved field */
2340
    *pos++ = 0;
2341

    
2342
    /* Encode the NLRI */
2343
    lr = bgp_encode_nlri(s, buck, pos, end - la);
2344
    pos += lr;
2345

    
2346
    /* End of MP_REACH_NLRI atribute, update data length */
2347
    put_u16(buf+6, pos-buf-8);
2348

    
2349
    /* Copy remaining attributes */
2350
    memcpy(pos, abuf, la);
2351
    pos += la;
2352

    
2353
    /* Initial UPDATE fields */
2354
    put_u16(buf+0, 0);
2355
    put_u16(buf+2, pos-buf-4);
2356

    
2357
    return pos;
2358
}
2359

    
2360
#undef MAX_ATTRS_LENGTH
2361

    
2362
/**
2363
 * For updates with withdrow reachability information
2364
 * @param s
2365
 * @param buck
2366
 * @param buf
2367
 * @param end
2368
 * @return
2369
 */
2370
static byte *
2371
bgp_create_ip_unreach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2372
{
2373
    /*
2374
     *        2 B        Withdrawn Routes Length
2375
     *        var        IPv4 Withdrawn Routes NLRI
2376
     *        2 B        Total Path Attribute Length (zero)
2377
     *        ---        Path Attributes (unused)
2378
     *        ---        IPv4 Network Layer Reachability Information (unused)
2379
     */
2380
    uint len = bgp_encode_nlri(s, buck, buf+2, end);
2381

    
2382
    put_u16(buf+0, len);
2383
    put_u16(buf+2+len, 0);
2384

    
2385
    return buf+4+len;
2386
}
2387

    
2388
static byte *
2389
bgp_create_mp_unreach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2390
{
2391
    /*
2392
     *        2 B        Withdrawn Routes Length (zero)
2393
     *        ---        IPv4 Withdrawn Routes NLRI (unused)
2394
     *        2 B        Total Path Attribute Length
2395
     *        1 B        MP_UNREACH_NLRI hdr - Attribute Flags
2396
     *        1 B        MP_UNREACH_NLRI hdr - Attribute Type Code
2397
     *        2 B        MP_UNREACH_NLRI hdr - Length of Attribute Data
2398
     *        2 B        MP_UNREACH_NLRI data - Address Family Identifier
2399
     *        1 B        MP_UNREACH_NLRI data - Subsequent Address Family Identifier
2400
     *        var        MP_UNREACH_NLRI data - Network Layer Reachability Information
2401
     *        ---        IPv4 Network Layer Reachability Information (unused)
2402
     */
2403

    
2404
    uint len = bgp_encode_nlri(s, buck, buf+11, end);
2405

    
2406
    put_u16(buf+0, 0);
2407
    put_u16(buf+2, 7+len);
2408

    
2409
    /* Begin of MP_UNREACH_NLRI atribute */
2410
    buf[4] = BAF_OPTIONAL | BAF_EXT_LEN;
2411
    buf[5] = BA_MP_UNREACH_NLRI;
2412
    put_u16(buf+6, 3+len);
2413
    put_af3(buf+8, s->channel->afi);
2414

    
2415
    return buf+11+len;
2416
}
2417

    
2418
/**
2419
 * Generic function to create an update
2420
 * @param c
2421
 * @param buf
2422
 * @return
2423
 */
2424
 //TODO sfruttare il bucket per reinoltrare gli update
2425
static byte *
2426
bgp_create_update(struct bgp_channel *c, byte *buf)
2427
{
2428
    struct bgp_proto *p = (void *) c->c.proto;
2429
    struct bgp_bucket *buck;
2430
    byte *end = buf + (bgp_max_packet_length(p->conn) - BGP_HEADER_LENGTH);
2431
    byte *res = NULL;
2432

    
2433
    again: ;
2434

    
2435
    /* Initialize write state */
2436
    struct bgp_write_state s = {
2437
            .proto = p,
2438
            .channel = c,
2439
            .pool = bgp_linpool,
2440
            .as4_session = p->as4_session,
2441
            .add_path = c->add_path_tx,
2442
            .mpls = c->desc->mpls,
2443
    };
2444

    
2445
    /* Try unreachable bucket */
2446
    //If there is information inside this bucket i will send a withdrow
2447
    if ((buck = c->withdraw_bucket) && !EMPTY_LIST(buck->prefixes))
2448
    {
2449
        res = (c->afi == BGP_AF_IPV4) && !c->ext_next_hop ?
2450
              bgp_create_ip_unreach(&s, buck, buf, end):
2451
              bgp_create_mp_unreach(&s, buck, buf, end);
2452

    
2453
        goto done;
2454
    }
2455

    
2456
    /* Try reachable buckets */
2457
    if (!EMPTY_LIST(c->bucket_queue)) //Il bucket degli indirizzi non è vuoto
2458
    {
2459
        buck = HEAD(c->bucket_queue);
2460

    
2461
        /* Cleanup empty buckets */
2462
        if (EMPTY_LIST(buck->prefixes))
2463
        {
2464
            bgp_free_bucket(c, buck);
2465
            goto again;
2466
        }
2467

    
2468
        res = (c->afi == BGP_AF_IPV4) && !c->ext_next_hop ?
2469
              bgp_create_ip_reach(&s, buck, buf, end):
2470
              bgp_create_mp_reach(&s, buck, buf, end);
2471

    
2472
        if (EMPTY_LIST(buck->prefixes))
2473
            bgp_free_bucket(c, buck);
2474
        else
2475
            bgp_defer_bucket(c, buck);
2476

    
2477
        if (!res)
2478
            goto again;
2479

    
2480
        goto done;
2481
    }
2482

    
2483
    /* No more prefixes to send */
2484
    return NULL;
2485

    
2486
    done:
2487
    BGP_TRACE_RL(&rl_snd_update, D_PACKETS, "Devo inviare un update");
2488
    //TODO spostare queste infor più su, solamente se res non è null
2489
    p->number_of_update_sent += 1;
2490
    total_number_of_update_sent += 1;
2491
    BGP_TRACE_RL(&rl_snd_update, D_PACKETS,"Numero totale di update inviati per questa conn: %d, pacchetti complessivi: %d", p->number_of_update_sent, total_number_of_update_sent);
2492
    BGP_TRACE_RL(&rl_snd_update, D_PACKETS, "Sending UPDATE");
2493
    lp_flush(s.pool);
2494

    
2495
    return res;
2496
}
2497

    
2498
static byte *
2499
bgp_create_ip_end_mark(struct bgp_channel *c UNUSED, byte *buf)
2500
{
2501
    /* Empty update packet */
2502
    put_u32(buf, 0);
2503

    
2504
    return buf+4;
2505
}
2506

    
2507
static byte *
2508
bgp_create_mp_end_mark(struct bgp_channel *c, byte *buf)
2509
{
2510
    put_u16(buf+0, 0);
2511
    put_u16(buf+2, 6);                /* length 4--9 */
2512

    
2513
    /* Empty MP_UNREACH_NLRI atribute */
2514
    buf[4] = BAF_OPTIONAL;
2515
    buf[5] = BA_MP_UNREACH_NLRI;
2516
    buf[6] = 3;                        /* Length 7--9 */
2517
    put_af3(buf+7, c->afi);
2518

    
2519
    return buf+10;
2520
}
2521

    
2522
static byte *
2523
bgp_create_end_mark(struct bgp_channel *c, byte *buf)
2524
{
2525
    struct bgp_proto *p = (void *) c->c.proto;
2526

    
2527
    BGP_TRACE(D_PACKETS, "Sending END-OF-RIB");
2528

    
2529
    return (c->afi == BGP_AF_IPV4) ?
2530
           bgp_create_ip_end_mark(c, buf):
2531
           bgp_create_mp_end_mark(c, buf);
2532
}
2533

    
2534
static inline void
2535
bgp_rx_end_mark(struct bgp_parse_state *s, u32 afi)
2536
{
2537
    struct bgp_proto *p = s->proto;
2538
    struct bgp_channel *c = bgp_get_channel(p, afi);
2539

    
2540
    BGP_TRACE(D_PACKETS, "Got END-OF-RIB");
2541

    
2542
    if (!c)
2543
        DISCARD(BAD_AFI, BGP_AFI(afi), BGP_SAFI(afi));
2544

    
2545
    if (c->load_state == BFS_LOADING)
2546
        c->load_state = BFS_NONE;
2547

    
2548
    if (p->p.gr_recovery)
2549
        channel_graceful_restart_unlock(&c->c);
2550

    
2551
    if (c->gr_active)
2552
        bgp_graceful_restart_done(c);
2553
}
2554

    
2555
/**
2556
 * Generic NLRI decode, to invoke the specific NLRI decoder
2557
 * @param s
2558
 * @param afi
2559
 * @param nlri
2560
 * @param len
2561
 * @param ea
2562
 * @param nh
2563
 * @param nh_len
2564
 */
2565
static inline void
2566
bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_list *ea, byte *nh, uint nh_len)
2567
{
2568
    struct bgp_channel *c = bgp_get_channel(s->proto, afi);
2569
    rta *a = NULL;
2570

    
2571
    if (!c)
2572
        DISCARD(BAD_AFI, BGP_AFI(afi), BGP_SAFI(afi));
2573

    
2574
    s->channel = c;
2575
    s->add_path = c->add_path_rx;
2576
    s->mpls = c->desc->mpls;
2577

    
2578
    s->last_id = 0;
2579
    s->last_src = s->proto->p.main_source;
2580

    
2581
    //TODO gne
2582
    if(nh_len == 0){
2583
        //log(L_INFO "Trovato withdraw");
2584
        withdraw_checker = 1;
2585
    }
2586

    
2587
    /*
2588
     * IPv4 BGP and MP-BGP may be used together in one update, therefore we do not
2589
     * add BA_NEXT_HOP in bgp_decode_attrs(), but we add it here independently for
2590
     * IPv4 BGP and MP-BGP. We undo the attribute (and possibly others attached by
2591
     * decode_next_hop hooks) by restoring a->eattrs afterwards.
2592
     */
2593

    
2594
    if (ea)
2595
    {
2596
        a = allocz(RTA_MAX_SIZE);
2597

    
2598
        a->source = RTS_BGP;
2599
        a->scope = SCOPE_UNIVERSE;
2600
        a->from = s->proto->cf->remote_ip;
2601
        a->eattrs = ea;
2602

    
2603
        c->desc->decode_next_hop(s, nh, nh_len, a);
2604

    
2605
        /* Handle withdraw during next hop decoding */
2606
        if (s->err_withdraw)
2607
            a = NULL;
2608
    }
2609

    
2610
    c->desc->decode_nlri(s, nlri, len, a);
2611
    rta_free(s->cached_rta);
2612
    s->cached_rta = NULL;
2613
}
2614

    
2615
static inline struct bgp_channel *
2616
bgp_get_channel_to_send(struct bgp_proto *p, struct bgp_conn *conn)
2617
{
2618
    uint i = conn->last_channel;
2619

    
2620
    /* Try the last channel, but at most several times */
2621
    if ((conn->channels_to_send & (1 << i)) &&
2622
        (conn->last_channel_count < 16))
2623
        goto found;
2624

    
2625
    /* Find channel with non-zero channels_to_send */
2626
    do
2627
    {
2628
        i++;
2629
        if (i >= p->channel_count)
2630
            i = 0;
2631
    }
2632
    while (! (conn->channels_to_send & (1 << i)));
2633

    
2634
    /* Use that channel */
2635
    conn->last_channel = i;
2636
    conn->last_channel_count = 0;
2637

    
2638
    found:
2639
    conn->last_channel_count++;
2640
    return p->channel_map[i];
2641
}
2642

    
2643
static void
2644
bgp_rx_update(struct bgp_conn *conn, byte *pkt, uint len)
2645
{
2646
    char output[50];
2647
    float tmpLoad = loadComplessivo;
2648
    snprintf(output, 50, "%f", loadComplessivo);
2649

    
2650
    withdraw_checker = 0;
2651
    struct bgp_proto *p = conn->bgp;
2652
    snprintf(ASLocale, 12, "%d", p->public_as);
2653

    
2654
    ea_list *ea = NULL;
2655

    
2656
    rilevatoLoop = 0;
2657
    ASRicezione = p->remote_as;
2658
    BGP_TRACE_RL(&rl_rcv_update, D_PACKETS, "Got UPDATE");
2659

    
2660
    /* Workaround for some BGP implementations that skip initial KEEPALIVE */
2661
    if (conn->state == BS_OPENCONFIRM)
2662
        bgp_conn_enter_established_state(conn);
2663

    
2664
    if (conn->state != BS_ESTABLISHED)
2665
    { bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0); return; }
2666

    
2667
    bgp_start_timer(conn->hold_timer, conn->hold_time);
2668

    
2669
    /* Initialize parse state */
2670
    struct bgp_parse_state s = {
2671
            .proto = p,
2672
            .pool = bgp_linpool,
2673
            .as4_session = p->as4_session,
2674
    };
2675

    
2676
    /* Parse error handler */
2677
    if (setjmp(s.err_jmpbuf))
2678
    {
2679
        bgp_error(conn, 3, s.err_subcode, NULL, 0);
2680
        goto done;
2681
    }
2682

    
2683
    /* Check minimal length */
2684
    if (len < 23)
2685
    { bgp_error(conn, 1, 2, pkt+16, 2); return; }
2686

    
2687
    /* Skip fixed header */
2688
    uint pos = 19;
2689

    
2690
    /*
2691
     *        UPDATE message format
2692
     *
2693
     *        2 B        IPv4 Withdrawn Routes Length
2694
     *        var        IPv4 Withdrawn Routes NLRI
2695
     *        2 B        Total Path Attribute Length
2696
     *        var        Path Attributes
2697
     *        var        IPv4 Reachable Routes NLRI
2698
     */
2699

    
2700
    s.ip_unreach_len = get_u16(pkt + pos);
2701
    s.ip_unreach_nlri = pkt + pos + 2;
2702
    pos += 2 + s.ip_unreach_len;
2703

    
2704
    if (pos + 2 > len)
2705
        bgp_parse_error(&s, 1);
2706

    
2707
    s.attr_len = get_u16(pkt + pos);
2708
    s.attrs = pkt + pos + 2;
2709
    pos += 2 + s.attr_len;
2710

    
2711
    if (pos > len)
2712
        bgp_parse_error(&s, 1);
2713

    
2714
    s.ip_reach_len = len - pos;
2715
    s.ip_reach_nlri = pkt + pos;
2716

    
2717
    sonoIlNH = 0;
2718
    numeroNHarrivati = 0.0;
2719
    loadOutRilevato = 0.0;
2720
    if (s.attr_len)
2721
        ea = bgp_decode_attrs(&s, s.attrs, s.attr_len);
2722
    else
2723
        ea = NULL;
2724

    
2725
    /* Check for End-of-RIB marker */
2726
    if (!s.attr_len && !s.ip_unreach_len && !s.ip_reach_len)
2727
    { bgp_rx_end_mark(&s, BGP_AF_IPV4); goto done; }
2728

    
2729
    /* Check for MP End-of-RIB marker */
2730
    if ((s.attr_len < 8) && !s.ip_unreach_len && !s.ip_reach_len &&
2731
        !s.mp_reach_len && !s.mp_unreach_len && s.mp_unreach_af)
2732
    { bgp_rx_end_mark(&s, s.mp_unreach_af); goto done; }
2733

    
2734
    if (s.ip_unreach_len)
2735
        bgp_decode_nlri(&s, BGP_AF_IPV4, s.ip_unreach_nlri, s.ip_unreach_len, NULL, NULL, 0);
2736

    
2737
    if (s.mp_unreach_len)
2738
        bgp_decode_nlri(&s, s.mp_unreach_af, s.mp_unreach_nlri, s.mp_unreach_len, NULL, NULL, 0);
2739

    
2740
    if (s.ip_reach_len)
2741
        bgp_decode_nlri(&s, BGP_AF_IPV4, s.ip_reach_nlri, s.ip_reach_len,
2742
                        ea, s.ip_next_hop_data, s.ip_next_hop_len);
2743

    
2744
    if (s.mp_reach_len)
2745
        bgp_decode_nlri(&s, s.mp_reach_af, s.mp_reach_nlri, s.mp_reach_len,
2746
                        ea, s.mp_next_hop_data, s.mp_next_hop_len);
2747

    
2748
    done:
2749
    rta_free(s.cached_rta);
2750
    lp_flush(s.pool);
2751

    
2752
    //TODO code refactoring
2753
    if (tmpLoad != loadComplessivo){
2754
        log(L_INFO "LOAD COMPLESSIVO VARIATO");
2755

    
2756
        RTable *objFound = map_get(&RTmap, cKey);
2757
        if (objFound == NULL){
2758
            log(L_INFO "objfound è null");
2759
        }
2760
        else if (objFound->P == NULL){
2761
            log(L_INFO "objFound->P è null");
2762
        }
2763
        else if (objFound->C == NULL){
2764
            log(L_INFO "objFound->C è null");
2765
        }
2766
        else if (objFound->n == NULL){
2767
            log(L_INFO "objFound->n è null");
2768
        }
2769
        else if (objFound->rtElem == NULL){
2770
            log(L_INFO "objFound->rtElem è null");
2771
        }
2772
        else if (objFound->ea == NULL){
2773
            log(L_INFO "objFound->ea è null");
2774
        }
2775
        else {
2776
            int tmp = 0;
2777
            int i = 0;
2778
            //bgp_show_proto_info_mine((void *)objFound->P);
2779
            map_iter_t iter3 = map_iter(&objFound->NH);
2780
            const char *key3;
2781
            while ((key3 = map_next(&objFound->NH, &iter3))) {
2782
                i++;
2783
                int *NHmap = map_get(&objFound->NH, key3);
2784
                if (*NHmap == ASRicezione) {
2785
                    tmp = 1;
2786
                }
2787
            }
2788
            if (tmp == 0 && i > 0) {
2789
                //Force RT_notify
2790
                //objFound->P->rt_notify(objFound->P, objFound->C, objFound->n, objFound->rtElem, NULL, objFound->rtElem->attrs->eattrs);
2791
                /*ea = objFound->rtElem->attrs->eattrs;
2792
                struct bgp_proto *pr = (void *)objFound->P;
2793
                struct bgp_channel *ch = (void *)objFound->C;
2794
                rte *new = objFound->rtElem;
2795
                net *n = objFound->n;
2796
                struct bgp_bucket *buck;
2797
                struct bgp_prefix *px;
2798
                u32 path;
2799
                ea = bgp_update_attrs(pr, ch, new, ea, bgp_linpool2);
2800
                if(ea) {
2801
                    buck = bgp_get_bucket(ch, ea);
2802
                    path = new->attrs->src->global_id;
2803
                    lp_flush(bgp_linpool2);
2804
                    px = bgp_get_prefix(ch, n->n.addr, ch->add_path_tx ? path : 0);
2805
                    add_tail(&buck->prefixes, &px->buck_node);
2806
                    bgp_schedule_packet(pr->conn, ch, PKT_UPDATE);
2807
                }*/
2808
            }
2809
        }
2810
    } else {
2811
        log(L_INFO "Load complessivo invariato");
2812
    }
2813

    
2814
    return;
2815
}
2816

    
2817

    
2818
/*
2819
 *        ROUTE-REFRESH
2820
 */
2821

    
2822
static inline byte *
2823
bgp_create_route_refresh(struct bgp_channel *c, byte *buf)
2824
{
2825
    struct bgp_proto *p = (void *) c->c.proto;
2826

    
2827
    BGP_TRACE(D_PACKETS, "Sending ROUTE-REFRESH");
2828

    
2829
    /* Original route refresh request, RFC 2918 */
2830
    put_af4(buf, c->afi);
2831
    buf[2] = BGP_RR_REQUEST;
2832

    
2833
    return buf+4;
2834
}
2835

    
2836
static inline byte *
2837
bgp_create_begin_refresh(struct bgp_channel *c, byte *buf)
2838
{
2839
    struct bgp_proto *p = (void *) c->c.proto;
2840

    
2841
    BGP_TRACE(D_PACKETS, "Sending BEGIN-OF-RR");
2842

    
2843
    /* Demarcation of beginning of route refresh (BoRR), RFC 7313 */
2844
    put_af4(buf, c->afi);
2845
    buf[2] = BGP_RR_BEGIN;
2846

    
2847
    return buf+4;
2848
}
2849

    
2850
static inline byte *
2851
bgp_create_end_refresh(struct bgp_channel *c, byte *buf)
2852
{
2853
    struct bgp_proto *p = (void *) c->c.proto;
2854

    
2855
    BGP_TRACE(D_PACKETS, "Sending END-OF-RR");
2856

    
2857
    /* Demarcation of ending of route refresh (EoRR), RFC 7313 */
2858
    put_af4(buf, c->afi);
2859
    buf[2] = BGP_RR_END;
2860

    
2861
    return buf+4;
2862
}
2863

    
2864
static void
2865
bgp_rx_route_refresh(struct bgp_conn *conn, byte *pkt, uint len)
2866
{
2867
    struct bgp_proto *p = conn->bgp;
2868

    
2869
    if (conn->state != BS_ESTABLISHED)
2870
    { bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0); return; }
2871

    
2872
    if (!conn->local_caps->route_refresh)
2873
    { bgp_error(conn, 1, 3, pkt+18, 1); return; }
2874

    
2875
    if (len < (BGP_HEADER_LENGTH + 4))
2876
    { bgp_error(conn, 1, 2, pkt+16, 2); return; }
2877

    
2878
    if (len > (BGP_HEADER_LENGTH + 4))
2879
    { bgp_error(conn, 7, 1, pkt, MIN(len, 2048)); return; }
2880

    
2881
    struct bgp_channel *c = bgp_get_channel(p, get_af4(pkt+19));
2882
    if (!c)
2883
    {
2884
        log(L_WARN "%s: Got ROUTE-REFRESH subtype %u for AF %u.%u, ignoring",
2885
                p->p.name, pkt[21], get_u16(pkt+19), pkt[22]);
2886
        return;
2887
    }
2888

    
2889
    /* RFC 7313 redefined reserved field as RR message subtype */
2890
    uint subtype = p->enhanced_refresh ? pkt[21] : BGP_RR_REQUEST;
2891

    
2892
    switch (subtype)
2893
    {
2894
        case BGP_RR_REQUEST:
2895
            BGP_TRACE(D_PACKETS, "Got ROUTE-REFRESH");
2896
            channel_request_feeding(&c->c);
2897
            break;
2898

    
2899
        case BGP_RR_BEGIN:
2900
            BGP_TRACE(D_PACKETS, "Got BEGIN-OF-RR");
2901
            bgp_refresh_begin(c);
2902
            break;
2903

    
2904
        case BGP_RR_END:
2905
            BGP_TRACE(D_PACKETS, "Got END-OF-RR");
2906
            bgp_refresh_end(c);
2907
            break;
2908

    
2909
        default:
2910
            log(L_WARN "%s: Got ROUTE-REFRESH message with unknown subtype %u, ignoring",
2911
            p->p.name, subtype);
2912
            break;
2913
    }
2914
}
2915

    
2916
static inline int
2917
bgp_send(struct bgp_conn *conn, uint type, uint len)
2918
{
2919
    sock *sk = conn->sk;
2920
    byte *buf = sk->tbuf;
2921

    
2922
    memset(buf, 0xff, 16);                /* Marker */
2923
    put_u16(buf+16, len);
2924
    buf[18] = type;
2925

    
2926
    return sk_send(sk, len);
2927
}
2928

    
2929
/**
2930
 * bgp_fire_tx - transmit packets
2931
 * @conn: connection
2932
 *
2933
 * Whenever the transmit buffers of the underlying TCP connection
2934
 * are free and we have any packets queued for sending, the socket functions
2935
 * call bgp_fire_tx() which takes care of selecting the highest priority packet
2936
 * queued (Notification > Keepalive > Open > Update), assembling its header
2937
 * and body and sending it to the connection.
2938
 */
2939
static int
2940
bgp_fire_tx(struct bgp_conn *conn)
2941
{
2942
    struct bgp_proto *p = conn->bgp;
2943
    struct bgp_channel *c;
2944
    byte *buf, *pkt, *end;
2945
    uint s;
2946

    
2947
    if (!conn->sk)
2948
        return 0;
2949

    
2950
    buf = conn->sk->tbuf;
2951
    pkt = buf + BGP_HEADER_LENGTH;
2952
    s = conn->packets_to_send;
2953

    
2954
    if (s & (1 << PKT_SCHEDULE_CLOSE))
2955
    {
2956
        /* We can finally close connection and enter idle state */
2957
        bgp_conn_enter_idle_state(conn);
2958
        return 0;
2959
    }
2960
    if (s & (1 << PKT_NOTIFICATION))
2961
    {
2962
        conn->packets_to_send = 1 << PKT_SCHEDULE_CLOSE;
2963
        end = bgp_create_notification(conn, pkt);
2964
        return bgp_send(conn, PKT_NOTIFICATION, end - buf);
2965
    }
2966
    else if (s & (1 << PKT_KEEPALIVE))
2967
    {
2968
        conn->packets_to_send &= ~(1 << PKT_KEEPALIVE);
2969
        BGP_TRACE(D_PACKETS, "Sending KEEPALIVE");
2970
        bgp_start_timer(conn->keepalive_timer, conn->keepalive_time);
2971
        return bgp_send(conn, PKT_KEEPALIVE, BGP_HEADER_LENGTH);
2972
    }
2973
    else if (s & (1 << PKT_OPEN))
2974
    {
2975
        conn->packets_to_send &= ~(1 << PKT_OPEN);
2976
        end = bgp_create_open(conn, pkt);
2977
        return bgp_send(conn, PKT_OPEN, end - buf);
2978
    }
2979
    else while (conn->channels_to_send)
2980
        {
2981
            c = bgp_get_channel_to_send(p, conn);
2982
            s = c->packets_to_send;
2983

    
2984
            if (s & (1 << PKT_ROUTE_REFRESH))
2985
            {
2986
                c->packets_to_send &= ~(1 << PKT_ROUTE_REFRESH);
2987
                end = bgp_create_route_refresh(c, pkt);
2988
                return bgp_send(conn, PKT_ROUTE_REFRESH, end - buf);
2989
            }
2990
            else if (s & (1 << PKT_BEGIN_REFRESH))
2991
            {
2992
                /* BoRR is a subtype of RR, but uses separate bit in packets_to_send */
2993
                c->packets_to_send &= ~(1 << PKT_BEGIN_REFRESH);
2994
                end = bgp_create_begin_refresh(c, pkt);
2995
                return bgp_send(conn, PKT_ROUTE_REFRESH, end - buf);
2996
            }
2997
            else if (s & (1 << PKT_UPDATE))
2998
            {
2999
                BGP_TRACE(D_PACKETS, "Ho un pkt di UPDATE da inviare");
3000
                end = bgp_create_update(c, pkt);
3001
                if (end){
3002
                    BGP_TRACE(D_PACKETS, "CONFERMATO PKT UPDATE");
3003
                    return bgp_send(conn, PKT_UPDATE, end - buf);
3004
                }
3005

    
3006
                /* No update to send, perhaps we need to send End-of-RIB or EoRR */
3007
                BGP_TRACE(D_PACKETS, "MERDA");
3008
                c->packets_to_send = 0;
3009
                conn->channels_to_send &= ~(1 << c->index);
3010

    
3011
                if (c->feed_state == BFS_LOADED)
3012
                {
3013
                    c->feed_state = BFS_NONE;
3014
                    end = bgp_create_end_mark(c, pkt);
3015
                    return bgp_send(conn, PKT_UPDATE, end - buf);
3016
                }
3017

    
3018
                else if (c->feed_state == BFS_REFRESHED)
3019
                {
3020
                    c->feed_state = BFS_NONE;
3021
                    end = bgp_create_end_refresh(c, pkt);
3022
                    return bgp_send(conn, PKT_ROUTE_REFRESH, end - buf);
3023
                }
3024
            }
3025
            else if (s)
3026
                bug("Channel packets_to_send: %x", s);
3027

    
3028
            c->packets_to_send = 0;
3029
            conn->channels_to_send &= ~(1 << c->index);
3030
        }
3031

    
3032
    return 0;
3033
}
3034

    
3035
/**
3036
 * bgp_schedule_packet - schedule a packet for transmission
3037
 * @conn: connection
3038
 * @c: channel
3039
 * @type: packet type
3040
 *
3041
 * Schedule a packet of type @type to be sent as soon as possible.
3042
 */
3043
void
3044
bgp_schedule_packet(struct bgp_conn *conn, struct bgp_channel *c, int type)
3045
{
3046
    ASSERT(conn->sk);
3047

    
3048
    DBG("BGP: Scheduling packet type %d\n", type);
3049
    if (c)
3050
    {
3051
        if (! conn->channels_to_send)
3052
        {
3053
            conn->last_channel = c->index;
3054
            conn->last_channel_count = 0;
3055
        }
3056
        c->packets_to_send |= 1 << type;
3057
        conn->channels_to_send |= 1 << c->index;
3058
    }
3059
    else
3060
        conn->packets_to_send |= 1 << type;
3061

    
3062
    if ((conn->sk->tpos == conn->sk->tbuf) && !ev_active(conn->tx_ev)) {
3063
        ev_schedule(conn->tx_ev);
3064
    }
3065
}
3066

    
3067
void
3068
bgp_kick_tx(void *vconn)
3069
{
3070
    struct bgp_conn *conn = vconn;
3071
    DBG("BGP: kicking TX\n");
3072

    
3073
    while (bgp_fire_tx(conn) > 0)
3074
        ;
3075
}
3076

    
3077
void
3078
bgp_tx(sock *sk)
3079
{
3080
    struct bgp_conn *conn = sk->data;
3081
    DBG("BGP: TX hook\n");
3082
    while (bgp_fire_tx(conn) > 0)
3083
        ;
3084
}
3085

    
3086

    
3087
static struct {
3088
    byte major, minor;
3089
    byte *msg;
3090
} bgp_msg_table[] = {
3091
        { 1, 0, "Invalid message header" },
3092
        { 1, 1, "Connection not synchronized" },
3093
        { 1, 2, "Bad message length" },
3094
        { 1, 3, "Bad message type" },
3095
        { 2, 0, "Invalid OPEN message" },
3096
        { 2, 1, "Unsupported version number" },
3097
        { 2, 2, "Bad peer AS" },
3098
        { 2, 3, "Bad BGP identifier" },
3099
        { 2, 4, "Unsupported optional parameter" },
3100
        { 2, 5, "Authentication failure" },
3101
        { 2, 6, "Unacceptable hold time" },
3102
        { 2, 7, "Required capability missing" }, /* [RFC5492] */
3103
        { 2, 8, "No supported AFI/SAFI" }, /* This error msg is nonstandard */
3104
        { 3, 0, "Invalid UPDATE message" },
3105
        { 3, 1, "Malformed attribute list" },
3106
        { 3, 2, "Unrecognized well-known attribute" },
3107
        { 3, 3, "Missing mandatory attribute" },
3108
        { 3, 4, "Invalid attribute flags" },
3109
        { 3, 5, "Invalid attribute length" },
3110
        { 3, 6, "Invalid ORIGIN attribute" },
3111
        { 3, 7, "AS routing loop" },                /* Deprecated */
3112
        { 3, 8, "Invalid NEXT_HOP attribute" },
3113
        { 3, 9, "Optional attribute error" },
3114
        { 3, 10, "Invalid network field" },
3115
        { 3, 11, "Malformed AS_PATH" },
3116
        { 4, 0, "Hold timer expired" },
3117
        { 5, 0, "Finite state machine error" }, /* Subcodes are according to [RFC6608] */
3118
        { 5, 1, "Unexpected message in OpenSent state" },
3119
        { 5, 2, "Unexpected message in OpenConfirm state" },
3120
        { 5, 3, "Unexpected message in Established state" },
3121
        { 6, 0, "Cease" }, /* Subcodes are according to [RFC4486] */
3122
        { 6, 1, "Maximum number of prefixes reached" },
3123
        { 6, 2, "Administrative shutdown" },
3124
        { 6, 3, "Peer de-configured" },
3125
        { 6, 4, "Administrative reset" },
3126
        { 6, 5, "Connection rejected" },
3127
        { 6, 6, "Other configuration change" },
3128
        { 6, 7, "Connection collision resolution" },
3129
        { 6, 8, "Out of Resources" },
3130
        { 7, 0, "Invalid ROUTE-REFRESH message" }, /* [RFC7313] */
3131
        { 7, 1, "Invalid ROUTE-REFRESH message length" } /* [RFC7313] */
3132
};
3133

    
3134
/**
3135
 * bgp_error_dsc - return BGP error description
3136
 * @code: BGP error code
3137
 * @subcode: BGP error subcode
3138
 *
3139
 * bgp_error_dsc() returns error description for BGP errors
3140
 * which might be static string or given temporary buffer.
3141
 */
3142
const char *
3143
bgp_error_dsc(uint code, uint subcode)
3144
{
3145
    static char buff[32];
3146
    uint i;
3147

    
3148
    for (i=0; i < ARRAY_SIZE(bgp_msg_table); i++)
3149
        if (bgp_msg_table[i].major == code && bgp_msg_table[i].minor == subcode)
3150
            return bgp_msg_table[i].msg;
3151

    
3152
    bsprintf(buff, "Unknown error %u.%u", code, subcode);
3153
    return buff;
3154
}
3155

    
3156
/* RFC 8203 - shutdown communication message */
3157
static int
3158
bgp_handle_message(struct bgp_proto *p, byte *data, uint len, byte **bp)
3159
{
3160
    byte *msg = data + 1;
3161
    uint msg_len = data[0];
3162
    uint i;
3163

    
3164
    /* Handle zero length message */
3165
    if (msg_len == 0)
3166
        return 1;
3167

    
3168
    /* Handle proper message */
3169
    if ((msg_len > 128) && (msg_len + 1 > len))
3170
        return 0;
3171

    
3172
    /* Some elementary cleanup */
3173
    for (i = 0; i < msg_len; i++)
3174
        if (msg[i] < ' ')
3175
            msg[i] = ' ';
3176

    
3177
    proto_set_message(&p->p, msg, msg_len);
3178
    *bp += bsprintf(*bp, ": \"%s\"", p->p.message);
3179
    return 1;
3180
}
3181

    
3182
void
3183
bgp_log_error(struct bgp_proto *p, u8 class, char *msg, uint code, uint subcode, byte *data, uint len)
3184
{
3185
    byte argbuf[256], *t = argbuf;
3186
    uint i;
3187

    
3188
    /* Don't report Cease messages generated by myself */
3189
    if (code == 6 && class == BE_BGP_TX)
3190
    return;
3191

    
3192
    /* Reset shutdown message */
3193
    if ((code == 6) && ((subcode == 2) || (subcode == 4)))
3194
        proto_set_message(&p->p, NULL, 0);
3195

    
3196
    if (len)
3197
    {
3198
        /* Bad peer AS - we would like to print the AS */
3199
        if ((code == 2) && (subcode == 2) && ((len == 2) || (len == 4)))
3200
        {
3201
            t += bsprintf(t, ": %u", (len == 2) ? get_u16(data) : get_u32(data));
3202
            goto done;
3203
        }
3204

    
3205
        /* RFC 8203 - shutdown communication */
3206
        if (((code == 6) && ((subcode == 2) || (subcode == 4))))
3207
            if (bgp_handle_message(p, data, len, &t))
3208
                goto done;
3209

    
3210
        *t++ = ':';
3211
        *t++ = ' ';
3212
        if (len > 16)
3213
            len = 16;
3214
        for (i=0; i<len; i++)
3215
            t += bsprintf(t, "%02x", data[i]);
3216
    }
3217

    
3218
    done:
3219
    *t = 0;
3220
    const byte *dsc = bgp_error_dsc(code, subcode);
3221
    log(L_REMOTE "%s: %s: %s%s", p->p.name, msg, dsc, argbuf);
3222
}
3223

    
3224
static void
3225
bgp_rx_notification(struct bgp_conn *conn, byte *pkt, uint len)
3226
{
3227
    struct bgp_proto *p = conn->bgp;
3228

    
3229
    if (len < 21)
3230
    { bgp_error(conn, 1, 2, pkt+16, 2); return; }
3231

    
3232
    uint code = pkt[19];
3233
    uint subcode = pkt[20];
3234
    int err = (code != 6);
3235

    
3236
    bgp_log_error(p, BE_BGP_RX, "Received", code, subcode, pkt+21, len-21);
3237
    bgp_store_error(p, conn, BE_BGP_RX, (code << 16) | subcode);
3238

    
3239
    bgp_conn_enter_close_state(conn);
3240
    bgp_schedule_packet(conn, NULL, PKT_SCHEDULE_CLOSE);
3241

    
3242
    if (err)
3243
    {
3244
        bgp_update_startup_delay(p);
3245
        bgp_stop(p, 0, NULL, 0);
3246
    }
3247
}
3248

    
3249
static void
3250
bgp_rx_keepalive(struct bgp_conn *conn)
3251
{
3252
    struct bgp_proto *p = conn->bgp;
3253

    
3254
    BGP_TRACE(D_PACKETS, "Got KEEPALIVE");
3255
    bgp_start_timer(conn->hold_timer, conn->hold_time);
3256

    
3257
    if (conn->state == BS_OPENCONFIRM)
3258
    { bgp_conn_enter_established_state(conn); return; }
3259

    
3260
    if (conn->state != BS_ESTABLISHED)
3261
        bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0);
3262
}
3263

    
3264

    
3265
/**
3266
 * bgp_rx_packet - handle a received packet
3267
 * @conn: BGP connection
3268
 * @pkt: start of the packet
3269
 * @len: packet size
3270
 *
3271
 * bgp_rx_packet() takes a newly received packet and calls the corresponding
3272
 * packet handler according to the packet type.
3273
 */
3274
static void
3275
bgp_rx_packet(struct bgp_conn *conn, byte *pkt, uint len)
3276
{
3277
    byte type = pkt[18];
3278

    
3279
    DBG("BGP: Got packet %02x (%d bytes)\n", type, len);
3280

    
3281
    if (conn->bgp->p.mrtdump & MD_MESSAGES)
3282
        mrt_dump_bgp_packet(conn, pkt, len);
3283

    
3284
    switch (type)
3285
    {
3286
        case PKT_OPEN:                return bgp_rx_open(conn, pkt, len);
3287
        case PKT_UPDATE:                return bgp_rx_update(conn, pkt, len);
3288
        case PKT_NOTIFICATION:        return bgp_rx_notification(conn, pkt, len);
3289
        case PKT_KEEPALIVE:                return bgp_rx_keepalive(conn);
3290
        case PKT_ROUTE_REFRESH:        return bgp_rx_route_refresh(conn, pkt, len);
3291
        default:                        bgp_error(conn, 1, 3, pkt+18, 1);
3292
    }
3293
}
3294

    
3295
/**
3296
 * bgp_rx - handle received data
3297
 * @sk: socket
3298
 * @size: amount of data received
3299
 *
3300
 * bgp_rx() is called by the socket layer whenever new data arrive from
3301
 * the underlying TCP connection. It assembles the data fragments to packets,
3302
 * checks their headers and framing and passes complete packets to
3303
 * bgp_rx_packet().
3304
 */
3305
int
3306
bgp_rx(sock *sk, uint size)
3307
{
3308
    struct bgp_conn *conn = sk->data;
3309
    byte *pkt_start = sk->rbuf;
3310
    byte *end = pkt_start + size;
3311
    uint i, len;
3312

    
3313
    DBG("BGP: RX hook: Got %d bytes\n", size);
3314
    while (end >= pkt_start + BGP_HEADER_LENGTH)
3315
    {
3316
        if ((conn->state == BS_CLOSE) || (conn->sk != sk))
3317
            return 0;
3318
        for(i=0; i<16; i++)
3319
            if (pkt_start[i] != 0xff)
3320
            {
3321
                bgp_error(conn, 1, 1, NULL, 0);
3322
                break;
3323
            }
3324
        len = get_u16(pkt_start+16);
3325
        if ((len < BGP_HEADER_LENGTH) || (len > bgp_max_packet_length(conn)))
3326
        {
3327
            bgp_error(conn, 1, 2, pkt_start+16, 2);
3328
            break;
3329
        }
3330
        if (end < pkt_start + len)
3331
            break;
3332
        bgp_rx_packet(conn, pkt_start, len);
3333
        pkt_start += len;
3334
    }
3335
    if (pkt_start != sk->rbuf)
3336
    {
3337
        memmove(sk->rbuf, pkt_start, end - pkt_start);
3338
        sk->rpos = sk->rbuf + (end - pkt_start);
3339
    }
3340
    return 0;
3341
}