Statistics
| Branch: | Revision:

iof-bird-daemon / proto / bgp / packets.c @ c8236a50

History | View | Annotate | Download (118 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
    ip4_addr addr4 = get_ip4(data);
995
    ip4_ntop(addr4, next_hop_ip);
996
    //net_addr_ip4 net = NET_ADDR_IP4(ip4_ntoh(addr4), len);
997
    //net_normalize_ip4(&net);
998
    //log(L_FATAL "Address nh ip: %I4", net.prefix);
999
}
1000

    
1001
static uint
1002
bgp_encode_next_hop_vpn(struct bgp_write_state *s, eattr *a, byte *buf, uint size UNUSED)
1003
{
1004
    ip_addr *nh = (void *) a->u.ptr->data;
1005
    uint len = a->u.ptr->length;
1006

    
1007
    ASSERT((len == 16) || (len == 32));
1008

    
1009
    /*
1010
     * Both IPv4 and IPv6 next hops can be used (with ext_next_hop enabled). This
1011
     * is specified in RFC 5549 for VPNv4 and in RFC 4659 for VPNv6. The difference
1012
     * is that IPv4 address is directly encoded with VPNv4 NLRI, but as IPv4-mapped
1013
     * IPv6 address with VPNv6 NLRI.
1014
     */
1015

    
1016
    if (bgp_channel_is_ipv4(s->channel) && ipa_is_ip4(nh[0]))
1017
    {
1018
        put_u64(buf, 0); /* VPN RD is 0 */
1019
        put_ip4(buf+8, ipa_to_ip4(nh[0]));
1020
        return 12;
1021
    }
1022

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

    
1026
    if (len == 16)
1027
        return 24;
1028

    
1029
    put_u64(buf+24, 0); /* VPN RD is 0 */
1030
    put_ip6(buf+32, ipa_to_ip6(nh[1]));
1031

    
1032
    return 48;
1033
}
1034

    
1035
static void
1036
bgp_decode_next_hop_vpn(struct bgp_parse_state *s, byte *data, uint len, rta *a)
1037
{
1038
    struct bgp_channel *c = s->channel;
1039
    struct adata *ad = lp_alloc_adata(s->pool, 32);
1040
    ip_addr *nh = (void *) ad->data;
1041

    
1042
    if (len == 12)
1043
    {
1044
        nh[0] = ipa_from_ip4(get_ip4(data+8));
1045
        nh[1] = IPA_NONE;
1046
    }
1047
    else if (len == 24)
1048
    {
1049
        nh[0] = ipa_from_ip6(get_ip6(data+8));
1050
        nh[1] = IPA_NONE;
1051

    
1052
        if (ipa_is_link_local(nh[0]))
1053
        { nh[1] = nh[0]; nh[0] = IPA_NONE; }
1054
    }
1055
    else if (len == 48)
1056
    {
1057
        nh[0] = ipa_from_ip6(get_ip6(data+8));
1058
        nh[1] = ipa_from_ip6(get_ip6(data+32));
1059

    
1060
        if (ipa_is_ip4(nh[0]) || !ip6_is_link_local(nh[1]))
1061
            nh[1] = IPA_NONE;
1062
    }
1063
    else
1064
        bgp_parse_error(s, 9);
1065

    
1066
    if (ipa_zero(nh[1]))
1067
        ad->length = 16;
1068

    
1069
    /* XXXX which error */
1070
    if ((get_u64(data) != 0) || ((len == 48) && (get_u64(data+24) != 0)))
1071
        bgp_parse_error(s, 9);
1072

    
1073
    if ((bgp_channel_is_ipv4(c) != ipa_is_ip4(nh[0])) && !c->ext_next_hop)
1074
        WITHDRAW(BAD_NEXT_HOP);
1075

    
1076
    // XXXX validate next hop
1077

    
1078
    bgp_set_attr_ptr(&(a->eattrs), s->pool, BA_NEXT_HOP, 0, ad);
1079
    bgp_apply_next_hop(s, a, nh[0], nh[1]);
1080
}
1081

    
1082
/**
1083
 * USELESS FUNCTION??
1084
 * @param s
1085
 * @param a
1086
 * @param buf
1087
 * @param size
1088
 * @return
1089
 */
1090
static uint
1091
bgp_encode_next_hop_none(struct bgp_write_state *s UNUSED, eattr *a UNUSED, byte *buf UNUSED, uint size UNUSED)
1092
{
1093
    return 0;
1094
}
1095

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

    
1105
    return;
1106
}
1107

    
1108
static void
1109
bgp_update_next_hop_none(struct bgp_export_state *s, eattr *a, ea_list **to)
1110
{
1111
    /* NEXT_HOP shall not pass */
1112
    if (a)
1113
        bgp_unset_attr(to, s->pool, BA_NEXT_HOP);
1114
}
1115

    
1116

    
1117
/*
1118
 *        UPDATE
1119
 */
1120

    
1121
static void
1122
bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0)
1123
{
1124
    //log(L_INFO "BGP_RTE_UPDATE");
1125
    if (path_id != s->last_id)
1126
    {
1127
        //log(L_FATAL "Path id != s->last_id: %lu, %lu", path_id, s->last_id);
1128
        s->last_src = rt_get_source(&s->proto->p, path_id);
1129
        s->last_id = path_id;
1130

    
1131
        rta_free(s->cached_rta);
1132
        s->cached_rta = NULL;
1133
    } else {
1134
        //log(L_FATAL "Path id == s->last_id: %lu, %lu", path_id, s->last_id);
1135
    }
1136
    if (!a0)
1137
    {
1138
        rte_update2(&s->channel->c, n, NULL, s->last_src);
1139
        return;
1140
    }
1141
    /* Prepare cached route attributes */
1142
    if (s->cached_rta == NULL)
1143
    {
1144
        a0->src = s->last_src;
1145

    
1146
        /* Workaround for rta_lookup() breaking eattrs */
1147
        ea_list *ea = a0->eattrs;
1148
        s->cached_rta = rta_lookup(a0);
1149
        a0->eattrs = ea;
1150
    }
1151

    
1152
    rta *a = rta_clone(s->cached_rta);
1153
    rte *e = rte_get_temp(a);
1154
    e->pflags = 0;
1155
    e->u.bgp.suppressed = 0;
1156
    struct channel *c = &s->channel->c;
1157
    struct proto_stats *stats = &c->stats;
1158

    
1159
    //log(L_INFO "s->channel->c->stats->imp_updates_ignored: %d",stats->imp_updates_ignored);
1160
    //log(L_INFO "s->channel->c->stats->imp_routes: %d",stats->imp_routes);
1161
    //How much updates are ignored
1162
    uint old_imp_updates_ignored = stats->imp_updates_ignored;
1163

    
1164

    
1165
    rte_update2(&s->channel->c, n, e, s->last_src);
1166
    //log(L_INFO "s->channel->c->stats->imp_updates_ignored: %d",stats->imp_updates_ignored);
1167
    //log(L_INFO "s->channel->c->stats->imp_routes: %d",stats->imp_routes);
1168

    
1169
    //TODO check to best updates
1170
    //Check if the update was ignored by rte_update2
1171
    /*if(stats->imp_updates_ignored > old_imp_updates_ignored){
1172
        RTable *objFound = map_get(&RTmap, cKey);
1173
        const char *keyTmp;
1174
        map_iter_t iterator = map_iter(&objFound->NH);
1175
        int i = 0;
1176
        while ((keyTmp = map_next(&objFound->NH, &iterator))) {
1177
            i++;
1178
        }
1179
        if(i!=1)
1180
            updateNHmap(0);
1181
    }
1182

1183
    RTable *objFound = map_get(&RTmap, cKey);
1184
    if(objFound != NULL) {
1185
        //Set atributes of the route
1186
        if(objFound->primaVolta == 1) {
1187
            //log(L_INFO "Ho trovato primavolta == 1 dunque devo aggiornare i dati");
1188
            objFound->P = c->proto;
1189
            objFound->C = c;
1190
            objFound->n = net_get(c->table, n);
1191
            objFound->rtElem = e;
1192
            objFound->primaVolta = 0;
1193
        }
1194
    }*/
1195
}
1196

    
1197
static void
1198
bgp_encode_mpls_labels(struct bgp_write_state *s UNUSED, adata *mpls, byte **pos, uint *size, byte *pxlen)
1199
{
1200
    u32 dummy = 0;
1201
    u32 *labels = mpls ? (u32 *) mpls->data : &dummy;
1202
    uint lnum = mpls ? (mpls->length / 4) : 1;
1203

    
1204
    for (uint i = 0; i < lnum; i++)
1205
    {
1206
        put_u24(*pos, labels[i] << 4);
1207
        ADVANCE(*pos, *size, 3);
1208
    }
1209

    
1210
    /* Add bottom-of-stack flag */
1211
    (*pos)[-1] |= BGP_MPLS_BOS;
1212

    
1213
    *pxlen += 24 * lnum;
1214
}
1215

    
1216
static void
1217
bgp_decode_mpls_labels(struct bgp_parse_state *s, byte **pos, uint *len, uint *pxlen, rta *a)
1218
{
1219
    u32 labels[BGP_MPLS_MAX], label;
1220
    uint lnum = 0;
1221

    
1222
    do {
1223
        if (*pxlen < 24)
1224
            bgp_parse_error(s, 1);
1225

    
1226
        label = get_u24(*pos);
1227
        labels[lnum++] = label >> 4;
1228
        ADVANCE(*pos, *len, 3);
1229
        *pxlen -= 24;
1230

    
1231
        /* Withdraw: Magic label stack value 0x800000 according to RFC 3107, section 3, last paragraph */
1232
        if (!a && !s->err_withdraw && (lnum == 1) && (label == BGP_MPLS_MAGIC))
1233
            break;
1234
    }
1235
    while (!(label & BGP_MPLS_BOS));
1236

    
1237
    if (!a)
1238
        return;
1239

    
1240
    /* Attach MPLS attribute unless we already have one */
1241
    if (!s->mpls_labels)
1242
    {
1243
        s->mpls_labels = lp_alloc_adata(s->pool, 4*BGP_MPLS_MAX);
1244
        bgp_set_attr_ptr(&(a->eattrs), s->pool, BA_MPLS_LABEL_STACK, 0, s->mpls_labels);
1245
    }
1246

    
1247
    /* Overwrite data in the attribute */
1248
    s->mpls_labels->length = 4*lnum;
1249
    memcpy(s->mpls_labels->data, labels, 4*lnum);
1250

    
1251
    /* Update next hop entry in rta */
1252
    bgp_apply_mpls_labels(s, a, labels, lnum);
1253

    
1254
    /* Attributes were changed, invalidate cached entry */
1255
    rta_free(s->cached_rta);
1256
    s->cached_rta = NULL;
1257

    
1258
    return;
1259
}
1260

    
1261
/*
1262
 *        Prefix hash table
1263
 */
1264

    
1265
#define PXH_KEY(px)                px->net, px->path_id, px->hash
1266
#define PXH_NEXT(px)                px->next
1267
//I have no idea of what I'm reading in the line below
1268
#define PXH_EQ(n1,i1,h1,n2,i2,h2) h1 == h2 && i1 == i2 && net_equal(n1, n2)
1269
#define PXH_FN(n,i,h)                h
1270

    
1271
#define PXH_REHASH                bgp_pxh_rehash
1272
#define PXH_PARAMS                /8, *2, 2, 2, 8, 20
1273

    
1274

    
1275
HASH_DEFINE_REHASH_FN(PXH, struct bgp_prefix)
1276

    
1277
static struct bgp_bucket *
1278
bgp_get_delayed_bucket()
1279
{
1280
    if (!delayed_bucket)
1281
    {
1282
        delayed_bucket = mb_allocz(proto_pool, sizeof(struct bgp_bucket));
1283
        init_list(&delayed_bucket->prefixes);
1284
    }
1285

    
1286
    return delayed_bucket;
1287
}
1288

    
1289
/**
1290
 * Function used to encode a prexif in the knowledge of the AS inside the packet
1291
 * @param s state
1292
 * @param buck bucket where to get the prefix
1293
 * @param buf
1294
 * @param size
1295
 * @return
1296
 */
1297
static uint
1298
bgp_encode_nlri_ip4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
1299
{
1300
    byte *pos = buf;
1301

    
1302
    log(L_INFO "encode nlri NO mrai");
1303

    
1304
    while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
1305
    {
1306
        struct bgp_prefix *px = HEAD(buck->prefixes);
1307
        struct net_addr_ip4 *net = (void *) px->net;
1308

    
1309
        /* Encode path ID */
1310
        if (s->add_path)
1311
        {
1312
            put_u32(pos, px->path_id);
1313
            ADVANCE(pos, size, 4);
1314
        }
1315

    
1316
        /* Encode prefix length */
1317
        *pos = net->pxlen;
1318
        ADVANCE(pos, size, 1);
1319

    
1320
        /* Encode MPLS labels */
1321
        if (s->mpls)
1322
            bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
1323

    
1324
        /* Encode prefix body */
1325
        ip4_addr a = ip4_hton(net->prefix);
1326
        ip4_ntop(net->prefix, dest_ip);
1327
        uint b = (net->pxlen + 7) / 8;
1328
        memcpy(pos, &a, b);
1329
        ADVANCE(pos, size, b);
1330

    
1331
        bgp_free_prefix(s->channel, px);
1332
    }
1333

    
1334
    return pos - buf;
1335
}
1336

    
1337
int
1338
already_in_conn_list(list *connections, struct bgp_conn *conn){
1339
    struct conn_list_node *obj;
1340
    WALK_LIST(obj, *connections){
1341
        if (obj->conn == conn){
1342
            return 1;
1343
        }
1344
    }
1345
    return 0;
1346
}
1347

    
1348
/**
1349
 * Function used to encode a prexif in the knowledge of the AS inside the packet
1350
 * Using the MRAI destintion timer model
1351
 * @param s state
1352
 * @param buck bucket where to get the prefix
1353
 * @param buf
1354
 * @param size
1355
 * @return
1356
 */
1357
static uint
1358
bgp_encode_nlri_ip4_mrai(struct bgp_conn *conn, struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
1359
{
1360
    byte *pos = buf;
1361

    
1362

    
1363
    log(L_INFO "encode nlri mrai, list len: %d",list_length(&buck->prefixes));
1364
    struct bgp_prefix *px;
1365
    int jumped = 0;
1366
    /* Scorrimento della lista dei prefissi, walk list first aka while che prevede l'eliminazione dell'oggetto */
1367
    WALK_LIST_FIRST(px, buck->prefixes)
1368
    {
1369
        /* Se tutti gli elementi sono stati saltati interrompo il while */
1370
        if(jumped == list_length(&buck->prefixes)){
1371
            log(L_INFO "interrupted for a jump");
1372
            break;
1373
        }
1374
        //while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX)){
1375
        if (size >= BGP_NLRI_MAX) {
1376
            //struct bgp_prefix *px = HEAD(buck->prefixes);
1377
            struct net_addr_ip4 *net = (void *) px->net;
1378

    
1379
            log(L_INFO
1380
            "Trovata nel bucket rete: %N", &px->net);
1381

    
1382
            /* create a second prefix from the first one */
1383
            struct bgp_prefix *tmp_prefix = HASH_FIND(sent_prefix_hash, PXH, px->net, px->path_id, px->hash);
1384
            if (!tmp_prefix) {
1385
                log(L_INFO
1386
                "Not found in the hash table");
1387
                if (sent_prefix_slab) {
1388
                    log(L_INFO
1389
                    "slab");
1390
                    tmp_prefix = sl_alloc(sent_prefix_slab);
1391
                } else {
1392
                    log(L_INFO
1393
                    "MB");
1394
                    tmp_prefix = mb_alloc(proto_pool, sizeof(struct bgp_prefix) + px->net->length);
1395
                }
1396
                /* Init tmp prefix parameters */
1397
                tmp_prefix->buck_node.next = NULL;
1398
                tmp_prefix->buck_node.prev = NULL;
1399
                tmp_prefix->hash = px->hash;
1400
                tmp_prefix->path_id = px->path_id;
1401
                log(L_INFO
1402
                "Len di px->net: %d", px->net->length);
1403
                net_copy(tmp_prefix->net, px->net);
1404
                tmp_prefix->sharing_time = current_time();
1405
                tmp_prefix->end_mrai = current_time() + conn->bgp->cf->mrai_time MS;
1406

    
1407
                init_list(&tmp_prefix->connections);
1408

    
1409
                /* Timer settings */
1410
                tmp_prefix->dest_mrai_timer = tm_new_init(proto_pool, dest_mrai_timeout, &tmp_prefix->connections, 0, 0);
1411
                bgp_start_ms_timer(tmp_prefix->dest_mrai_timer, conn->bgp->cf->mrai_time, conn->bgp->cf->mrai_jitter);
1412
                HASH_INSERT2(sent_prefix_hash, PXH, proto_pool, tmp_prefix);
1413

    
1414
                /* Add prefix to the delayed bucket */
1415
                struct bgp_bucket *buck;
1416
                buck = bgp_get_delayed_bucket();
1417
                add_tail(&buck->prefixes, &tmp_prefix->buck_node);
1418

    
1419
                /* Encode path ID */
1420
                if (s->add_path) {
1421
                    put_u32(pos, px->path_id);
1422
                    ADVANCE(pos, size, 4);
1423
                }
1424

    
1425
                /* Encode prefix length */
1426
                *pos = net->pxlen;
1427
                ADVANCE(pos, size, 1);
1428

    
1429
                /* Encode MPLS labels */
1430
                if (s->mpls)
1431
                    bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
1432

    
1433
                /* Encode prefix body */
1434
                ip4_addr a = ip4_hton(net->prefix);
1435
                ip4_ntop(net->prefix, dest_ip);
1436
                uint b = (net->pxlen + 7) / 8;
1437
                memcpy(pos, &a, b);
1438
                ADVANCE(pos, size, b);
1439
                bgp_free_prefix(s->channel, px);
1440
                prefixAdded++;
1441
            } else {
1442
                log(L_INFO
1443
                "Destinazione già all'interno della tabella");
1444
                if (!tm_active(tmp_prefix->dest_mrai_timer)){
1445
                    log(L_INFO
1446
                    "Il timer è finito");
1447

    
1448
                    /* Timer and tmp_prefix update */
1449
                    tmp_prefix->sharing_time = current_time();
1450
                    tmp_prefix->end_mrai = current_time() + conn->bgp->cf->mrai_time MS;
1451

    
1452
                    tmp_prefix->dest_mrai_timer = tm_new_init(proto_pool, dest_mrai_timeout, &tmp_prefix->connections, 0, 0);
1453
                    bgp_start_ms_timer(tmp_prefix->dest_mrai_timer, conn->bgp->cf->mrai_time, conn->bgp->cf->mrai_jitter);
1454

    
1455
                    /* Encode path ID */
1456
                    if (s->add_path) {
1457
                        put_u32(pos, px->path_id);
1458
                        ADVANCE(pos, size, 4);
1459
                    }
1460

    
1461
                    /* Encode prefix length */
1462
                    *pos = net->pxlen;
1463
                    ADVANCE(pos, size, 1);
1464

    
1465
                    /* Encode MPLS labels */
1466
                    if (s->mpls)
1467
                        bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
1468

    
1469
                    /* Encode prefix body */
1470
                    ip4_addr a = ip4_hton(net->prefix);
1471
                    ip4_ntop(net->prefix, dest_ip);
1472
                    uint b = (net->pxlen + 7) / 8;
1473
                    memcpy(pos, &a, b);
1474
                    ADVANCE(pos, size, b);
1475
                    bgp_free_prefix(s->channel, px);
1476
                    prefixAdded++;
1477
                } else {
1478

    
1479
                    /* Create connection element */
1480
                    struct conn_list_node *conn_node;
1481
                    if (connections_slab) {
1482
                        log(L_INFO
1483
                        "slab");
1484
                        conn_node = sl_alloc(connections_slab);
1485
                    } else {
1486
                        log(L_INFO
1487
                        "MB");
1488
                        conn_node = mb_alloc(proto_pool, sizeof(struct conn_list_node));
1489
                    }
1490
                    /* Init connection element */
1491
                    conn_node->conn_node.next = NULL;
1492
                    conn_node->conn_node.prev = NULL;
1493
                    conn_node->conn = conn;
1494

    
1495
                    /* Se la connection non è già in lista allora la aggiungo */
1496
                    if(!already_in_conn_list(&tmp_prefix->connections, conn)) {
1497
                        add_tail(&tmp_prefix->connections, &conn_node->conn_node);
1498
                    }
1499

    
1500
                    char share_time[TM_DATETIME_BUFFER_SIZE];
1501
                    tm_format_time(share_time, &TM_ISO_SHORT_MS, tmp_prefix->end_mrai);
1502
                    log(L_INFO
1503
                    "Il timer NON è finito, la rete %N potrà essere condivsa fino a: %s", &px->net, share_time);
1504
                    jumped++;
1505
                }
1506
            }
1507
        }
1508
    }
1509

    
1510
    return pos - buf;
1511
}
1512

    
1513
/**
1514
 * Function to print in the log the actual state of the map
1515
 */
1516
/*void statoAttualeDellaMappa(){
1517
    char *jsonOut = malloc(sizeof(char) * 2);
1518
    strcpy(jsonOut, "");
1519
    char *tmpJsonOut = malloc(sizeof(char) * 150);
1520

1521
    const char *key;
1522
    char output[50];
1523
    map_iter_t iter;
1524
    iter = map_iter(&RTmap);
1525

1526
    while ((key = map_next(&RTmap, &iter))) {
1527
        sprintf(tmpJsonOut, "keyAddress: %s {\n",key);
1528
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1529
        strcat(jsonOut, tmpJsonOut);
1530

1531
        RTable *d = map_get(&RTmap, key);
1532

1533
        sprintf(tmpJsonOut, "\tInterno: %d,\n\tNH: {\n",d->interno);
1534
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1535
        strcat(jsonOut, tmpJsonOut);
1536

1537
        const char *internalKey;
1538
        map_iter_t internIter;
1539
        internIter = map_iter(&d->NH);
1540

1541
        while((internalKey = map_next(&d->NH, &internIter))){
1542
            int *nh = map_get(&d->NH, internalKey);
1543
            sprintf(tmpJsonOut, "\t\tkeyNH: %s,\n\t\tValue: %d\n",internalKey, *nh);
1544
            jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1545
            strcat(jsonOut, tmpJsonOut);
1546
        }
1547

1548
        sprintf(tmpJsonOut, "\t},\n\tLoadIn: {\n");
1549
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1550
        strcat(jsonOut, tmpJsonOut);
1551

1552
        internIter = map_iter(&d->loadin);
1553
        while ((internalKey = map_next(&d->loadin, &internIter))) {
1554
            float *loadIn = map_get(&d->loadin, internalKey);
1555
            snprintf(output, 50, "%f", *loadIn);
1556
            sprintf(tmpJsonOut, "\t\tkey: %s,\n\t\tloadIn: %s\n",internalKey,output);
1557
            jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1558
            strcat(jsonOut, tmpJsonOut);
1559
        }
1560

1561
        snprintf(output, 50, "%f", d->load);
1562
        sprintf(tmpJsonOut, "\t},\n\tLoad: %s\n", output);
1563
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1564
        strcat(jsonOut, tmpJsonOut);
1565
        sprintf(tmpJsonOut, "}\n");
1566
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1567
        strcat(jsonOut, tmpJsonOut);
1568
    }
1569

1570
    sprintf(tmpJsonOut, "AS_LOAD: {\n");
1571
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1572
    strcat(jsonOut, tmpJsonOut);
1573

1574
    iter = map_iter(&ASLoad_map);
1575
    while ((key = map_next(&ASLoad_map, &iter))) {
1576
        ASLoad *ASLoad_element = map_get(&ASLoad_map, key);
1577
        snprintf(output, 50, "%f", ASLoad_element->load);
1578
        sprintf(tmpJsonOut, "\tkey: %s, Load: %s, metrica: %d,\n",key,output,ASLoad_element->metrica);
1579
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1580
        strcat(jsonOut, tmpJsonOut);
1581
    }
1582
    sprintf(tmpJsonOut, "}\n");
1583
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1584
    strcat(jsonOut, tmpJsonOut);
1585

1586
    snprintf(output, 50, "%f", loadComplessivo);
1587
    sprintf(tmpJsonOut, "loadComplessivo: %s\n",output);
1588
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1589
    strcat(jsonOut, tmpJsonOut);
1590

1591
    snprintf(output, 50, "%d", total_number_of_update_sent);
1592
    sprintf(tmpJsonOut, "total_number_of_update_sent: %s\n",output);
1593
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1594
    strcat(jsonOut, tmpJsonOut);
1595

1596
    //The length of the log message is limited, so i have to split the map if the dimension is not enough
1597
    if(strlen(jsonOut) > 980){
1598
        char *jsonOutPartial = malloc(sizeof(char) * 981);
1599
        memcpy(jsonOutPartial, jsonOut, 980);
1600
        free(jsonOutPartial);
1601
    }
1602

1603
    log(L_INFO "\n%s",jsonOut);
1604
    free(tmpJsonOut);
1605
    free(jsonOut);
1606
} */
1607

    
1608
/**
1609
 * Function to print the map into the log but with less informations
1610
 */
1611
/*void statoAttualeDellaMappaMinimal(){
1612
    char *jsonOut = malloc(sizeof(char) * 2);
1613
    char *tmpJsonOut = malloc(sizeof(char) * 150);
1614
    strcpy(jsonOut, "");
1615

1616
    char output[50];
1617
    const char *key;
1618
    map_iter_t iter;
1619

1620
    iter = map_iter(&ASLoad_map);
1621
    while ((key = map_next(&ASLoad_map, &iter))) {
1622
        ASLoad *ASLoad_element = map_get(&ASLoad_map, key);
1623
        snprintf(output, 50, "%f", ASLoad_element->load);
1624
        sprintf(tmpJsonOut, "\tkey: %s, Load: %s, metrica: %d;\n",key,output,ASLoad_element->metrica);
1625
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1626
        strcat(jsonOut, tmpJsonOut);
1627
    }
1628
    sprintf(tmpJsonOut, "}\n");
1629
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1630
    strcat(jsonOut, tmpJsonOut);
1631

1632
    snprintf(output, 50, "%f", loadComplessivo);
1633
    sprintf(tmpJsonOut, "loadComplessivo: %s,\n",output);
1634
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1635
    strcat(jsonOut, tmpJsonOut);
1636

1637
    snprintf(output, 50, "%d", total_number_of_update_sent);
1638
    sprintf(tmpJsonOut, "total_number_of_update_sent: %s,\n",output);
1639
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1640
    strcat(jsonOut, tmpJsonOut);
1641

1642
    int iterazioni = strlen(jsonOut) / 900;
1643
    if(strlen(jsonOut) % 900 > 0){
1644
        iterazioni++;
1645
    }
1646

1647
    //Split the message i more pieces
1648
    log(L_INFO "\nAS_LOAD: {");
1649
    char *jsonOutPartial;
1650
    char *pointerToJsonOutOriginal = jsonOut;
1651
    if(iterazioni > 1) {
1652
        jsonOutPartial = malloc(sizeof(char) * 901);
1653
        do {
1654
            memcpy(jsonOutPartial, jsonOut, 900);
1655
            jsonOut += 900;
1656
            jsonOutPartial[900] = '\0';
1657
            log(L_INFO "\n%s", jsonOutPartial);
1658
            memset(jsonOutPartial, 0, sizeof(*jsonOutPartial));
1659
        } while ((strlen(jsonOut) > 900));
1660
        if(strlen(jsonOut) > 0)
1661
            log(L_INFO "\n%s",jsonOut);
1662
        free(jsonOutPartial);
1663
    } else {
1664
        log(L_INFO "\n%s",jsonOut);
1665
    }
1666

1667
    log(L_INFO "\nIterazioni: %d", iterazioni);
1668
    jsonOut = NULL;
1669
    free(tmpJsonOut);
1670
    free(pointerToJsonOutOriginal);
1671
}*/
1672

    
1673
/**
1674
 * This is where the magic of DPC happen
1675
 * @param s
1676
 * @param pos
1677
 * @param len
1678
 * @param a
1679
 */
1680
static void
1681
bgp_decode_nlri_ip4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
1682
{
1683
    while (len)
1684
    {
1685
        net_addr_ip4 net;
1686
        u32 path_id = 0;
1687

    
1688
        /* Decode path ID */
1689
        if (s->add_path)
1690
        {
1691
            if (len < 5)
1692
                bgp_parse_error(s, 1);
1693

    
1694
            path_id = get_u32(pos);
1695
            ADVANCE(pos, len, 4);
1696
        }
1697

    
1698
        /* Decode prefix length */
1699
        uint l = *pos;
1700
        ADVANCE(pos, len, 1);
1701

    
1702
        if (len < ((l + 7) / 8))
1703
            bgp_parse_error(s, 1);
1704

    
1705
        /* Decode MPLS labels */
1706
        if (s->mpls)
1707
            bgp_decode_mpls_labels(s, &pos, &len, &l, a);
1708

    
1709
        if (l > IP4_MAX_PREFIX_LENGTH)
1710
            bgp_parse_error(s, 10);
1711

    
1712
        /* Decode prefix body */
1713
        ip4_addr addr = IP4_NONE;
1714
        uint b = (l + 7) / 8;
1715
        memcpy(&addr, pos, b);
1716
        ADVANCE(pos, len, b);
1717

    
1718
        net = NET_ADDR_IP4(ip4_ntoh(addr), l);
1719
        net_normalize_ip4(&net);
1720

    
1721
        net_addr *n = (net_addr *) &net;
1722

    
1723
        int keyAdr = n->data[0] + n->data[1] + n->data[2] + n->data[3];
1724
        char asCKey[12];
1725
        sprintf(cKey, "%d", keyAdr);
1726
        sprintf(nhCKey, "%d", nhKey);
1727
        sprintf(asCKey, "%d", ASRicezione);
1728

    
1729
        /*RTable *objFound;
1730
        map_iter_t iter;
1731
        const char *key;
1732
        int *NHmap;*/
1733
        //log(L_INFO "cKey: %s, nhCKey: %s, asCKey: %s", cKey, nhCKey, asCKey);
1734

    
1735
        //log(L_INFO "{type: UPDATE_RX, dest: %I4, from: %s, nh: %s}", net.prefix, asCKey, nhCKey);
1736

    
1737
        /*if(withdraw_checker != 0){ //Withdraw section
1738
            //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);
1739
            objFound = map_get(&RTmap, cKey);
1740
            if (objFound) {
1741
                iter = map_iter(&objFound->NH);
1742
                while ((key = map_next(&objFound->NH, &iter))) {
1743
                    NHmap = map_get(&objFound->NH, key);
1744
                    if (*NHmap == ASRicezione) {
1745
                        map_remove(&RTmap, cKey);
1746
                    }
1747
                }
1748
            }
1749
        }
1750
        else {
1751
            NhVecchio = 0;
1752
            if(rilevatoLoop != 1){
1753
                // Nessun loop, controllo se la destinazione esiste già nella mappa
1754
                objFound = map_get(&RTmap, cKey);
1755
                if (objFound) {
1756
                    // Destinazione già presente nella mappa, aggiungo il nexthop alla lista dei nexthop
1757
                    NHmap = map_get(&objFound->NH, nhCKey);
1758
                    if (NHmap) {
1759
                        //log(L_INFO "NH già presente nella lista, lo lascio");
1760
                        NhVecchio = 1;
1761
                        objFound->primaVolta = 1;
1762
                    } else {
1763
                        //log(L_INFO "NH non trovato nella mappa, lo aggiungo");
1764
                        if(map_set(&objFound->NH, &nhCKey[0], ASRicezione) != 0){
1765
                            log(L_INFO "Elemento non aggiunto alla mappa, ERROR");
1766
                        }
1767
                    }
1768
                } else {
1769
                    //log(L_INFO "Destinazione non trovata, aggiungo la destinazione ed il nexthop alla mappa dei nexthop");
1770
                    RTable rtElem = initRTableElement(n,0,1);
1771
                    if(map_set(&RTmap, &cKey[0], rtElem) == 0){
1772
                        //log(L_INFO "Elemento aggiunto alla mappa");
1773
                        objFound = map_get(&RTmap, cKey);
1774
                        map_set(&ExternalDestinationMap, &cKey[0], 1);
1775
                        //log(L_INFO "Aggiungo il nh per questa nuova destinazione");
1776
                        if(map_set(&objFound->NH, &nhCKey[0], ASRicezione) != 0){
1777
                            log(L_INFO "Elemento non aggiunto alla mappa, ERROR");
1778
                        }
1779
                        objFound->primaVolta = 1;
1780
                    }
1781
                }
1782
            }*/
1783

    
1784
            /*Manage load contributes*/
1785
            /*char output[50];
1786
            if(sonoIlNH == 1){
1787
                //log(L_INFO "Io sono tra i NH del mittente, cKey: %s", cKey);
1788
                objFound = map_get(&RTmap, cKey);
1789
                if(objFound != NULL) {
1790
                    if (objFound->interno != 0) { //Se io sono origine e NH allora non aggiungo niente, non ho carico in ingresso per le mie stesse destinazioni
1791
                        float *LoadInmap = map_get(&objFound->loadin, asCKey);
1792
                        if (LoadInmap) {
1793
                            //snprintf(output, 50, "%f", loadOutRilevato);
1794
                            //log(L_INFO "Aggiorno il valore loadIn per questo NH, loadOutRilevato: %s NNH: %d", output, numeroNHarrivati);
1795
                            *LoadInmap = loadOutRilevato / (numeroNHarrivati * 1.0);
1796
                            //snprintf(output, 50, "%f", *LoadInmap);
1797
                            //log(L_INFO "Nuovo valore: %s", output);
1798
                        } else {
1799
                            //snprintf(output, 50, "%f", loadOutRilevato);
1800
                            //log(L_INFO "LoadIn non trovato nella mappa, lo aggiungo key: %s, loadOutRilevato: %s NNH: %d", nhCKey, output, numeroNHarrivati);
1801
                            float valoreLoadIn = loadOutRilevato / (numeroNHarrivati * 1.0);
1802
                            if (map_set(&objFound->loadin, &asCKey[0], valoreLoadIn) != 0) {
1803
                                snprintf(output, 50, "%f", valoreLoadIn);
1804
                                log(L_INFO "Elemento NON aggiunto alla mappa con valore: %s, ERROR", output);
1805
                            }
1806
                        }
1807
                    }
1808
                }
1809
            } else {
1810
                //log(L_INFO "Io NON sono tra i NH del mittente, rimuovo leventuale loadin");
1811
                objFound = map_get(&RTmap, cKey);
1812
                if(objFound != NULL) {
1813
                    map_remove(&objFound->loadin, asCKey);
1814
                }
1815
            }
1816
        }
1817

1818
        loadComplessivo = 0;
1819

1820
        // Load accumulation
1821
        iter = map_iter(&RTmap);
1822
        while ((key = map_next(&RTmap, &iter))) {
1823
            RTable *d = map_get(&RTmap, key);
1824
            if(d != NULL) {
1825
                const char *key4;
1826
                map_iter_t iter4 = map_iter(&d->loadin);
1827
                while ((key4 = map_next(&d->loadin, &iter4))) {
1828
                    float *loadIn = map_get(&d->loadin, key4);
1829
                    if (loadIn != NULL) {
1830
                        loadComplessivo += *loadIn;
1831
                    }
1832
                }
1833
            }
1834
        }
1835

1836
        //Repropagation information
1837
        ASLoad *ASLoad_element = map_get(&ASLoad_map, ASLocale);
1838
        if (ASLoad_element) {
1839
            if (ASLoad_element->load != loadComplessivo) { // The local AS have some new metrics to annunce
1840
                ASLoad_element->load = loadComplessivo;
1841
                ASLoad_element->metrica += 1;
1842

1843
                map_iter_t iter = map_iter(&ASLoad_element->remoteMap);
1844
                while ((key = map_next(&ASLoad_element->remoteMap, &iter))) {
1845
                    map_remove(&ASLoad_element->remoteMap, key);
1846
                }
1847
            }
1848
        }*/
1849

    
1850
        //statoAttualeDellaMappaMinimal();
1851
        struct channel *c = &s->channel->c;
1852
        struct proto_stats *stats = &c->stats;
1853
        uint old_imp_updates_ignored = stats->imp_updates_ignored;
1854
        uint old_imp_updates_accepted = stats->imp_updates_accepted;
1855
        uint old_imp_updates_best_substitution = stats->imp_updates_best_substitution;
1856
        uint old_imp_updates_removed_route = stats->imp_updates_removed_route;
1857

    
1858
        struct network *old_net = net_get(c->table, (net_addr *) &net);
1859
        rte *old_best = old_net->routes;
1860
        sprintf(buf_old_best_as_path, "NONE");
1861
        if (old_best != NULL) {
1862
            struct rta *old_attrs = old_best->attrs;
1863
            if (old_attrs != NULL) {
1864
                struct ea_list *old_eattrs = old_attrs->eattrs;
1865
                eattr *e_attr_old = bgp_find_attr(old_eattrs, BA_AS_PATH);
1866
                if (e_attr_old != NULL) {
1867
                    struct adata *ad = (e_attr_old->type & EAF_EMBEDDED) ? NULL : e_attr_old->u.ptr;
1868
                    as_path_format(ad, buf_old_best_as_path, CLI_MSG_SIZE);
1869
                }
1870
            }
1871
        }
1872

    
1873
        bgp_rte_update(s, (net_addr *) &net, path_id, a); //call to the function that update the RT
1874
        //log(L_FATAL "old_ign: %d, new_ign: %d, old_acc: %d, new_acc: %d, old_bst: %d, new_bst: %d", old_imp_updates_ignored, stats->imp_updates_ignored,
1875
        //        old_imp_updates_accepted, stats->imp_updates_accepted, old_imp_updates_best_substitution, stats->imp_updates_best_substitution);
1876
        struct network *new_net = net_get(c->table, (net_addr *) &net);
1877
        rte *mew_best = new_net->routes;
1878
        sprintf(buf_new_best_as_path, "NONE");
1879
        if (mew_best != NULL) {
1880
            struct rta *new_attrs = mew_best->attrs;
1881
            if (new_attrs != NULL) {
1882
                struct ea_list *new_eattrs = new_attrs->eattrs;
1883
                eattr *e_attr_new = bgp_find_attr(new_eattrs, BA_AS_PATH);
1884
                if (e_attr_new != NULL) {
1885
                    struct adata *ad = (e_attr_new->type & EAF_EMBEDDED) ? NULL : e_attr_new->u.ptr;
1886
                    as_path_format(ad, buf_new_best_as_path, CLI_MSG_SIZE);
1887
                }
1888
            }
1889
        }
1890

    
1891
        if(stats->imp_updates_ignored > old_imp_updates_ignored){
1892
            log(L_FATAL "{type: UPDATE_RX, dest: %I4, from: %s, nh: %s, as_path: %s, previus_best_path: %s, actual_best_path: %s, processing: IGNORED}",
1893
                    net.prefix,
1894
                    asCKey,
1895
                    next_hop_ip,
1896
                    buf_as_path,
1897
                    buf_old_best_as_path,
1898
                    buf_new_best_as_path);
1899
        } else if (stats->imp_updates_accepted > old_imp_updates_accepted){
1900
            if (stats->imp_updates_best_substitution > old_imp_updates_best_substitution){
1901
                log(L_FATAL "{type: UPDATE_RX, dest: %I4, from: %s, nh: %s, as_path: %s, previus_best_path: %s, actual_best_path: %s, processing: NEW_BEST_PATH}",
1902
                        net.prefix,
1903
                        asCKey,
1904
                        next_hop_ip,
1905
                        buf_as_path,
1906
                        buf_old_best_as_path,
1907
                        buf_new_best_as_path);
1908
            } else {
1909
                log(L_FATAL "{type: UPDATE_RX, dest: %I4, from: %s, nh: %s, as_path: %s, previus_best_path: %s, actual_best_path: %s, processing: NEW_PATH}",
1910
                        net.prefix,
1911
                        asCKey,
1912
                        next_hop_ip,
1913
                        buf_as_path,
1914
                        buf_old_best_as_path,
1915
                        buf_new_best_as_path);
1916
            }
1917
        } else {
1918
            if(stats->imp_updates_removed_route > old_imp_updates_removed_route){
1919
                log(L_FATAL "{type: UPDATE_RX, dest: %I4, from: %s, nh: %s, as_path: %s, previus_best_path: %s, actual_best_path: %s, processing: REMOVED_REPLACED_PATH}",
1920
                        net.prefix,
1921
                        asCKey,
1922
                        next_hop_ip,
1923
                        buf_as_path,
1924
                        buf_old_best_as_path,
1925
                        buf_new_best_as_path);
1926
            }
1927
        }
1928
    }
1929
}
1930

    
1931

    
1932
//TODO do it for ipv6? :thinking:
1933
static uint
1934
bgp_encode_nlri_ip6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
1935
{
1936
    byte *pos = buf;
1937

    
1938
    while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
1939
    {
1940
        struct bgp_prefix *px = HEAD(buck->prefixes);
1941
        struct net_addr_ip6 *net = (void *) px->net;
1942

    
1943
        /* Encode path ID */
1944
        if (s->add_path)
1945
        {
1946
            put_u32(pos, px->path_id);
1947
            ADVANCE(pos, size, 4);
1948
        }
1949

    
1950
        /* Encode prefix length */
1951
        *pos = net->pxlen;
1952
        ADVANCE(pos, size, 1);
1953

    
1954
        /* Encode MPLS labels */
1955
        if (s->mpls)
1956
            bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
1957

    
1958
        /* Encode prefix body */
1959
        ip6_addr a = ip6_hton(net->prefix);
1960
        uint b = (net->pxlen + 7) / 8;
1961
        memcpy(pos, &a, b);
1962
        ADVANCE(pos, size, b);
1963

    
1964
        bgp_free_prefix(s->channel, px);
1965
    }
1966

    
1967
    return pos - buf;
1968
}
1969

    
1970
static void
1971
bgp_decode_nlri_ip6(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
1972
{
1973
    while (len)
1974
    {
1975
        net_addr_ip6 net;
1976
        u32 path_id = 0;
1977

    
1978
        /* Decode path ID */
1979
        if (s->add_path)
1980
        {
1981
            if (len < 5)
1982
                bgp_parse_error(s, 1);
1983

    
1984
            path_id = get_u32(pos);
1985
            ADVANCE(pos, len, 4);
1986
        }
1987

    
1988
        /* Decode prefix length */
1989
        uint l = *pos;
1990
        ADVANCE(pos, len, 1);
1991

    
1992
        if (len < ((l + 7) / 8))
1993
            bgp_parse_error(s, 1);
1994

    
1995
        /* Decode MPLS labels */
1996
        if (s->mpls)
1997
            bgp_decode_mpls_labels(s, &pos, &len, &l, a);
1998

    
1999
        if (l > IP6_MAX_PREFIX_LENGTH)
2000
            bgp_parse_error(s, 10);
2001

    
2002
        /* Decode prefix body */
2003
        ip6_addr addr = IP6_NONE;
2004
        uint b = (l + 7) / 8;
2005
        memcpy(&addr, pos, b);
2006
        ADVANCE(pos, len, b);
2007

    
2008
        net = NET_ADDR_IP6(ip6_ntoh(addr), l);
2009
        net_normalize_ip6(&net);
2010

    
2011
        // XXXX validate prefix
2012

    
2013
        bgp_rte_update(s, (net_addr *) &net, path_id, a);
2014
    }
2015
}
2016

    
2017
static uint
2018
bgp_encode_nlri_vpn4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
2019
{
2020
    byte *pos = buf;
2021

    
2022
    while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
2023
    {
2024
        struct bgp_prefix *px = HEAD(buck->prefixes);
2025
        struct net_addr_vpn4 *net = (void *) px->net;
2026

    
2027
        /* Encode path ID */
2028
        if (s->add_path)
2029
        {
2030
            put_u32(pos, px->path_id);
2031
            ADVANCE(pos, size, 4);
2032
        }
2033

    
2034
        /* Encode prefix length */
2035
        *pos = 64 + net->pxlen;
2036
        ADVANCE(pos, size, 1);
2037

    
2038
        /* Encode MPLS labels */
2039
        if (s->mpls)
2040
            bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
2041

    
2042
        /* Encode route distinguisher */
2043
        put_u64(pos, net->rd);
2044
        ADVANCE(pos, size, 8);
2045

    
2046
        /* Encode prefix body */
2047
        ip4_addr a = ip4_hton(net->prefix);
2048
        uint b = (net->pxlen + 7) / 8;
2049
        memcpy(pos, &a, b);
2050
        ADVANCE(pos, size, b);
2051

    
2052
        bgp_free_prefix(s->channel, px);
2053
    }
2054

    
2055
    return pos - buf;
2056
}
2057

    
2058
static void
2059
bgp_decode_nlri_vpn4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
2060
{
2061
    while (len)
2062
    {
2063
        net_addr_vpn4 net;
2064
        u32 path_id = 0;
2065

    
2066
        /* Decode path ID */
2067
        if (s->add_path)
2068
        {
2069
            if (len < 5)
2070
                bgp_parse_error(s, 1);
2071

    
2072
            path_id = get_u32(pos);
2073
            ADVANCE(pos, len, 4);
2074
        }
2075

    
2076
        /* Decode prefix length */
2077
        uint l = *pos;
2078
        ADVANCE(pos, len, 1);
2079

    
2080
        if (len < ((l + 7) / 8))
2081
            bgp_parse_error(s, 1);
2082

    
2083
        /* Decode MPLS labels */
2084
        if (s->mpls)
2085
            bgp_decode_mpls_labels(s, &pos, &len, &l, a);
2086

    
2087
        /* Decode route distinguisher */
2088
        if (l < 64)
2089
            bgp_parse_error(s, 1);
2090

    
2091
        u64 rd = get_u64(pos);
2092
        ADVANCE(pos, len, 8);
2093
        l -= 64;
2094

    
2095
        if (l > IP4_MAX_PREFIX_LENGTH)
2096
            bgp_parse_error(s, 10);
2097

    
2098
        /* Decode prefix body */
2099
        ip4_addr addr = IP4_NONE;
2100
        uint b = (l + 7) / 8;
2101
        memcpy(&addr, pos, b);
2102
        ADVANCE(pos, len, b);
2103

    
2104
        net = NET_ADDR_VPN4(ip4_ntoh(addr), l, rd);
2105
        net_normalize_vpn4(&net);
2106

    
2107
        // XXXX validate prefix
2108

    
2109
        bgp_rte_update(s, (net_addr *) &net, path_id, a);
2110
    }
2111
}
2112

    
2113
static uint
2114
bgp_encode_nlri_vpn6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
2115
{
2116
    byte *pos = buf;
2117

    
2118
    while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
2119
    {
2120
        struct bgp_prefix *px = HEAD(buck->prefixes);
2121
        struct net_addr_vpn6 *net = (void *) px->net;
2122

    
2123
        /* Encode path ID */
2124
        if (s->add_path)
2125
        {
2126
            put_u32(pos, px->path_id);
2127
            ADVANCE(pos, size, 4);
2128
        }
2129

    
2130
        /* Encode prefix length */
2131
        *pos = 64 + net->pxlen;
2132
        ADVANCE(pos, size, 1);
2133

    
2134
        /* Encode MPLS labels */
2135
        if (s->mpls)
2136
            bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
2137

    
2138
        /* Encode route distinguisher */
2139
        put_u64(pos, net->rd);
2140
        ADVANCE(pos, size, 8);
2141

    
2142
        /* Encode prefix body */
2143
        ip6_addr a = ip6_hton(net->prefix);
2144
        uint b = (net->pxlen + 7) / 8;
2145
        memcpy(pos, &a, b);
2146
        ADVANCE(pos, size, b);
2147

    
2148
        bgp_free_prefix(s->channel, px);
2149
    }
2150

    
2151
    return pos - buf;
2152
}
2153

    
2154
static void
2155
bgp_decode_nlri_vpn6(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
2156
{
2157
    while (len)
2158
    {
2159
        net_addr_vpn6 net;
2160
        u32 path_id = 0;
2161

    
2162
        /* Decode path ID */
2163
        if (s->add_path)
2164
        {
2165
            if (len < 5)
2166
                bgp_parse_error(s, 1);
2167

    
2168
            path_id = get_u32(pos);
2169
            ADVANCE(pos, len, 4);
2170
        }
2171

    
2172
        /* Decode prefix length */
2173
        uint l = *pos;
2174
        ADVANCE(pos, len, 1);
2175

    
2176
        if (len < ((l + 7) / 8))
2177
            bgp_parse_error(s, 1);
2178

    
2179
        /* Decode MPLS labels */
2180
        if (s->mpls)
2181
            bgp_decode_mpls_labels(s, &pos, &len, &l, a);
2182

    
2183
        /* Decode route distinguisher */
2184
        if (l < 64)
2185
            bgp_parse_error(s, 1);
2186

    
2187
        u64 rd = get_u64(pos);
2188
        ADVANCE(pos, len, 8);
2189
        l -= 64;
2190

    
2191
        if (l > IP6_MAX_PREFIX_LENGTH)
2192
            bgp_parse_error(s, 10);
2193

    
2194
        /* Decode prefix body */
2195
        ip6_addr addr = IP6_NONE;
2196
        uint b = (l + 7) / 8;
2197
        memcpy(&addr, pos, b);
2198
        ADVANCE(pos, len, b);
2199

    
2200
        net = NET_ADDR_VPN6(ip6_ntoh(addr), l, rd);
2201
        net_normalize_vpn6(&net);
2202

    
2203
        // XXXX validate prefix
2204

    
2205
        bgp_rte_update(s, (net_addr *) &net, path_id, a);
2206
    }
2207
}
2208

    
2209
static uint
2210
bgp_encode_nlri_flow4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
2211
{
2212
    byte *pos = buf;
2213

    
2214
    while (!EMPTY_LIST(buck->prefixes) && (size >= 4))
2215
    {
2216
        struct bgp_prefix *px = HEAD(buck->prefixes);
2217
        struct net_addr_flow4 *net = (void *) px->net;
2218
        uint flen = net->length - sizeof(net_addr_flow4);
2219

    
2220
        /* Encode path ID */
2221
        if (s->add_path)
2222
        {
2223
            put_u32(pos, px->path_id);
2224
            ADVANCE(pos, size, 4);
2225
        }
2226

    
2227
        if (flen > size)
2228
            break;
2229

    
2230
        /* Copy whole flow data including length */
2231
        memcpy(pos, net->data, flen);
2232
        ADVANCE(pos, size, flen);
2233

    
2234
        bgp_free_prefix(s->channel, px);
2235
    }
2236

    
2237
    return pos - buf;
2238
}
2239

    
2240
static void
2241
bgp_decode_nlri_flow4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
2242
{
2243
    while (len)
2244
    {
2245
        u32 path_id = 0;
2246

    
2247
        /* Decode path ID */
2248
        if (s->add_path)
2249
        {
2250
            if (len < 4)
2251
                bgp_parse_error(s, 1);
2252

    
2253
            path_id = get_u32(pos);
2254
            ADVANCE(pos, len, 4);
2255
        }
2256

    
2257
        if (len < 2)
2258
            bgp_parse_error(s, 1);
2259

    
2260
        /* Decode flow length */
2261
        uint hlen = flow_hdr_length(pos);
2262
        uint dlen = flow_read_length(pos);
2263
        uint flen = hlen + dlen;
2264
        byte *data = pos + hlen;
2265

    
2266
        if (len < flen)
2267
            bgp_parse_error(s, 1);
2268

    
2269
        /* Validate flow data */
2270
        enum flow_validated_state r = flow4_validate(data, dlen);
2271
        if (r != FLOW_ST_VALID)
2272
        {
2273
            log(L_REMOTE "%s: Invalid flow route: %s", s->proto->p.name, flow_validated_state_str(r));
2274
            bgp_parse_error(s, 1);
2275
        }
2276

    
2277
        if (data[0] != FLOW_TYPE_DST_PREFIX)
2278
        {
2279
            log(L_REMOTE "%s: No dst prefix at first pos", s->proto->p.name);
2280
            bgp_parse_error(s, 1);
2281
        }
2282

    
2283
        /* Decode dst prefix */
2284
        ip4_addr px = IP4_NONE;
2285
        uint pxlen = data[1];
2286

    
2287
        // FIXME: Use some generic function
2288
        memcpy(&px, data+2, BYTES(pxlen));
2289
        px = ip4_and(ip4_ntoh(px), ip4_mkmask(pxlen));
2290

    
2291
        /* Prepare the flow */
2292
        net_addr *n = alloca(sizeof(struct net_addr_flow4) + flen);
2293
        net_fill_flow4(n, px, pxlen, pos, flen);
2294
        ADVANCE(pos, len, flen);
2295

    
2296
        bgp_rte_update(s, n, path_id, a);
2297
    }
2298
}
2299

    
2300
static uint
2301
bgp_encode_nlri_flow6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
2302
{
2303
    byte *pos = buf;
2304

    
2305
    while (!EMPTY_LIST(buck->prefixes) && (size >= 4))
2306
    {
2307
        struct bgp_prefix *px = HEAD(buck->prefixes);
2308
        struct net_addr_flow6 *net = (void *) px->net;
2309
        uint flen = net->length - sizeof(net_addr_flow6);
2310

    
2311
        /* Encode path ID */
2312
        if (s->add_path)
2313
        {
2314
            put_u32(pos, px->path_id);
2315
            ADVANCE(pos, size, 4);
2316
        }
2317

    
2318
        if (flen > size)
2319
            break;
2320

    
2321
        /* Copy whole flow data including length */
2322
        memcpy(pos, net->data, flen);
2323
        ADVANCE(pos, size, flen);
2324

    
2325
        bgp_free_prefix(s->channel, px);
2326
    }
2327

    
2328
    return pos - buf;
2329
}
2330

    
2331
static void
2332
bgp_decode_nlri_flow6(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
2333
{
2334
    while (len)
2335
    {
2336
        u32 path_id = 0;
2337

    
2338
        /* Decode path ID */
2339
        if (s->add_path)
2340
        {
2341
            if (len < 4)
2342
                bgp_parse_error(s, 1);
2343

    
2344
            path_id = get_u32(pos);
2345
            ADVANCE(pos, len, 4);
2346
        }
2347

    
2348
        if (len < 2)
2349
            bgp_parse_error(s, 1);
2350

    
2351
        /* Decode flow length */
2352
        uint hlen = flow_hdr_length(pos);
2353
        uint dlen = flow_read_length(pos);
2354
        uint flen = hlen + dlen;
2355
        byte *data = pos + hlen;
2356

    
2357
        if (len < flen)
2358
            bgp_parse_error(s, 1);
2359

    
2360
        /* Validate flow data */
2361
        enum flow_validated_state r = flow6_validate(data, dlen);
2362
        if (r != FLOW_ST_VALID)
2363
        {
2364
            log(L_REMOTE "%s: Invalid flow route: %s", s->proto->p.name, flow_validated_state_str(r));
2365
            bgp_parse_error(s, 1);
2366
        }
2367

    
2368
        if (data[0] != FLOW_TYPE_DST_PREFIX)
2369
        {
2370
            log(L_REMOTE "%s: No dst prefix at first pos", s->proto->p.name);
2371
            bgp_parse_error(s, 1);
2372
        }
2373

    
2374
        /* Decode dst prefix */
2375
        ip6_addr px = IP6_NONE;
2376
        uint pxlen = data[1];
2377

    
2378
        // FIXME: Use some generic function
2379
        memcpy(&px, data+2, BYTES(pxlen));
2380
        px = ip6_and(ip6_ntoh(px), ip6_mkmask(pxlen));
2381

    
2382
        /* Prepare the flow */
2383
        net_addr *n = alloca(sizeof(struct net_addr_flow6) + flen);
2384
        net_fill_flow6(n, px, pxlen, pos, flen);
2385
        ADVANCE(pos, len, flen);
2386

    
2387
        bgp_rte_update(s, n, path_id, a);
2388
    }
2389
}
2390

    
2391
//This data structure define what function to use, it's used by external libraries
2392
static const struct bgp_af_desc bgp_af_table[] = {
2393
        {
2394
                .afi = BGP_AF_IPV4,
2395
                .net = NET_IP4,
2396
                .name = "ipv4",
2397
                .encode_nlri = bgp_encode_nlri_ip4,
2398
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2399
                .decode_nlri = bgp_decode_nlri_ip4,
2400
                .encode_next_hop = bgp_encode_next_hop_ip,
2401
                .decode_next_hop = bgp_decode_next_hop_ip,
2402
                .update_next_hop = bgp_update_next_hop_ip,
2403
        },
2404
        {
2405
                .afi = BGP_AF_IPV4_MC,
2406
                .net = NET_IP4,
2407
                .name = "ipv4-mc",
2408
                .encode_nlri = bgp_encode_nlri_ip4,
2409
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2410
                .decode_nlri = bgp_decode_nlri_ip4,
2411
                .encode_next_hop = bgp_encode_next_hop_ip,
2412
                .decode_next_hop = bgp_decode_next_hop_ip,
2413
                .update_next_hop = bgp_update_next_hop_ip,
2414
        },
2415
        {
2416
                .afi = BGP_AF_IPV4_MPLS,
2417
                .net = NET_IP4,
2418
                .mpls = 1,
2419
                .name = "ipv4-mpls",
2420
                .encode_nlri = bgp_encode_nlri_ip4,
2421
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2422
                .decode_nlri = bgp_decode_nlri_ip4,
2423
                .encode_next_hop = bgp_encode_next_hop_ip,
2424
                .decode_next_hop = bgp_decode_next_hop_ip,
2425
                .update_next_hop = bgp_update_next_hop_ip,
2426
        },
2427
        {
2428
                .afi = BGP_AF_IPV6,
2429
                .net = NET_IP6,
2430
                .name = "ipv6",
2431
                .encode_nlri = bgp_encode_nlri_ip6,
2432
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2433
                .decode_nlri = bgp_decode_nlri_ip6,
2434
                .encode_next_hop = bgp_encode_next_hop_ip,
2435
                .decode_next_hop = bgp_decode_next_hop_ip,
2436
                .update_next_hop = bgp_update_next_hop_ip,
2437
        },
2438
        {
2439
                .afi = BGP_AF_IPV6_MC,
2440
                .net = NET_IP6,
2441
                .name = "ipv6-mc",
2442
                .encode_nlri = bgp_encode_nlri_ip6,
2443
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2444
                .decode_nlri = bgp_decode_nlri_ip6,
2445
                .encode_next_hop = bgp_encode_next_hop_ip,
2446
                .decode_next_hop = bgp_decode_next_hop_ip,
2447
                .update_next_hop = bgp_update_next_hop_ip,
2448
        },
2449
        {
2450
                .afi = BGP_AF_IPV6_MPLS,
2451
                .net = NET_IP6,
2452
                .mpls = 1,
2453
                .name = "ipv6-mpls",
2454
                .encode_nlri = bgp_encode_nlri_ip6,
2455
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2456
                .decode_nlri = bgp_decode_nlri_ip6,
2457
                .encode_next_hop = bgp_encode_next_hop_ip,
2458
                .decode_next_hop = bgp_decode_next_hop_ip,
2459
                .update_next_hop = bgp_update_next_hop_ip,
2460
        },
2461
        {
2462
                .afi = BGP_AF_VPN4_MPLS,
2463
                .net = NET_VPN4,
2464
                .mpls = 1,
2465
                .name = "vpn4-mpls",
2466
                .encode_nlri = bgp_encode_nlri_vpn4,
2467
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2468
                .decode_nlri = bgp_decode_nlri_vpn4,
2469
                .encode_next_hop = bgp_encode_next_hop_vpn,
2470
                .decode_next_hop = bgp_decode_next_hop_vpn,
2471
                .update_next_hop = bgp_update_next_hop_ip,
2472
        },
2473
        {
2474
                .afi = BGP_AF_VPN6_MPLS,
2475
                .net = NET_VPN6,
2476
                .mpls = 1,
2477
                .name = "vpn6-mpls",
2478
                .encode_nlri = bgp_encode_nlri_vpn6,
2479
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2480
                .decode_nlri = bgp_decode_nlri_vpn6,
2481
                .encode_next_hop = bgp_encode_next_hop_vpn,
2482
                .decode_next_hop = bgp_decode_next_hop_vpn,
2483
                .update_next_hop = bgp_update_next_hop_ip,
2484
        },
2485
        {
2486
                .afi = BGP_AF_VPN4_MC,
2487
                .net = NET_VPN4,
2488
                .name = "vpn4-mc",
2489
                .encode_nlri = bgp_encode_nlri_vpn4,
2490
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2491
                .decode_nlri = bgp_decode_nlri_vpn4,
2492
                .encode_next_hop = bgp_encode_next_hop_vpn,
2493
                .decode_next_hop = bgp_decode_next_hop_vpn,
2494
                .update_next_hop = bgp_update_next_hop_ip,
2495
        },
2496
        {
2497
                .afi = BGP_AF_VPN6_MC,
2498
                .net = NET_VPN6,
2499
                .name = "vpn6-mc",
2500
                .encode_nlri = bgp_encode_nlri_vpn6,
2501
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2502
                .decode_nlri = bgp_decode_nlri_vpn6,
2503
                .encode_next_hop = bgp_encode_next_hop_vpn,
2504
                .decode_next_hop = bgp_decode_next_hop_vpn,
2505
                .update_next_hop = bgp_update_next_hop_ip,
2506
        },
2507
        {
2508
                .afi = BGP_AF_FLOW4,
2509
                .net = NET_FLOW4,
2510
                .no_igp = 1,
2511
                .name = "flow4",
2512
                .encode_nlri = bgp_encode_nlri_flow4,
2513
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2514
                .decode_nlri = bgp_decode_nlri_flow4,
2515
                .encode_next_hop = bgp_encode_next_hop_none,
2516
                .decode_next_hop = bgp_decode_next_hop_none,
2517
                .update_next_hop = bgp_update_next_hop_none,
2518
        },
2519
        {
2520
                .afi = BGP_AF_FLOW6,
2521
                .net = NET_FLOW6,
2522
                .no_igp = 1,
2523
                .name = "flow6",
2524
                .encode_nlri = bgp_encode_nlri_flow6,
2525
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2526
                .decode_nlri = bgp_decode_nlri_flow6,
2527
                .encode_next_hop = bgp_encode_next_hop_none,
2528
                .decode_next_hop = bgp_decode_next_hop_none,
2529
                .update_next_hop = bgp_update_next_hop_none,
2530
        },
2531
};
2532

    
2533
const struct bgp_af_desc *
2534
bgp_get_af_desc(u32 afi)
2535
{
2536
    uint i;
2537
    for (i = 0; i < ARRAY_SIZE(bgp_af_table); i++)
2538
        if (bgp_af_table[i].afi == afi)
2539
            return &bgp_af_table[i];
2540

    
2541
    return NULL;
2542
}
2543

    
2544
static inline uint
2545
bgp_encode_nlri(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2546
{
2547
    return s->channel->desc->encode_nlri(s, buck, buf, end - buf);
2548
}
2549

    
2550
static inline uint
2551
bgp_encode_nlri_mrai_destination_based(struct bgp_conn *conn, struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2552
{
2553
    return s->channel->desc->encode_nlri_mrai(conn, s, buck, buf, end - buf);
2554
}
2555

    
2556
static inline uint
2557
bgp_encode_next_hop(struct bgp_write_state *s, eattr *nh, byte *buf)
2558
{
2559
    return s->channel->desc->encode_next_hop(s, nh, buf, 255);
2560
}
2561

    
2562
void
2563
bgp_update_next_hop(struct bgp_export_state *s, eattr *a, ea_list **to)
2564
{
2565
    s->channel->desc->update_next_hop(s, a, to);
2566
}
2567

    
2568
#define MAX_ATTRS_LENGTH (end-buf+BGP_HEADER_LENGTH - 1024)
2569

    
2570
/**
2571
 * For updates with new reachability info
2572
 * @param s
2573
 * @param buck
2574
 * @param buf
2575
 * @param end
2576
 * @return
2577
 */
2578
static byte *
2579
bgp_create_ip_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2580
{
2581
    /*
2582
     *        2 B        Withdrawn Routes Length (zero)
2583
     *        ---        IPv4 Withdrawn Routes NLRI (unused)
2584
     *        2 B        Total Path Attribute Length
2585
     *        var        Path Attributes
2586
     *        var        IPv4 Network Layer Reachability Information
2587
     */
2588

    
2589
    int lr, la;
2590

    
2591
    la = bgp_encode_attrs(s, buck->eattrs, buf+4, buf + MAX_ATTRS_LENGTH);
2592

    
2593
    sprintf(buf_as_path, "NONE");
2594
    struct ea_list *eaList = buck->eattrs;
2595
    eattr *e_attr = bgp_find_attr(eaList, BA_AS_PATH);
2596
    if (e_attr != NULL) {
2597
        struct adata *ad = (e_attr->type & EAF_EMBEDDED) ? NULL : e_attr->u.ptr;
2598
        as_path_format(ad, buf_as_path, CLI_MSG_SIZE);
2599
    }
2600

    
2601
    if (la < 0)
2602
    {
2603
        /* Attribute list too long */
2604
        bgp_withdraw_bucket(s->channel, buck);
2605
        return NULL;
2606
    }
2607

    
2608
    put_u16(buf+0, 0);
2609
    put_u16(buf+2, la);
2610

    
2611
    sprintf(dest_ip, "NONE");
2612
    lr = bgp_encode_nlri(s, buck, buf+4+la, end);
2613

    
2614
    return buf+4+la+lr;
2615
}
2616

    
2617
/**
2618
 * For updates with new reachability info
2619
 * @param s
2620
 * @param buck
2621
 * @param buf
2622
 * @param end
2623
 * @return
2624
 */
2625
static byte *
2626
bgp_create_ip_reach_mrai_destination_based(struct bgp_conn *conn, struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2627
{
2628
    /*
2629
     *        2 B        Withdrawn Routes Length (zero)
2630
     *        ---        IPv4 Withdrawn Routes NLRI (unused)
2631
     *        2 B        Total Path Attribute Length
2632
     *        var        Path Attributes
2633
     *        var        IPv4 Network Layer Reachability Information
2634
     */
2635

    
2636
    int lr, la;
2637

    
2638
    la = bgp_encode_attrs(s, buck->eattrs, buf+4, buf + MAX_ATTRS_LENGTH);
2639

    
2640
    sprintf(buf_as_path, "NONE");
2641
    struct ea_list *eaList = buck->eattrs;
2642
    eattr *e_attr = bgp_find_attr(eaList, BA_AS_PATH);
2643
    if (e_attr != NULL) {
2644
        struct adata *ad = (e_attr->type & EAF_EMBEDDED) ? NULL : e_attr->u.ptr;
2645
        as_path_format(ad, buf_as_path, CLI_MSG_SIZE);
2646
    }
2647

    
2648
    if (la < 0)
2649
    {
2650
        /* Attribute list too long */
2651
        bgp_withdraw_bucket(s->channel, buck);
2652
        return NULL;
2653
    }
2654

    
2655
    put_u16(buf+0, 0);
2656
    put_u16(buf+2, la);
2657

    
2658
    sprintf(dest_ip, "NONE");
2659
    lr = bgp_encode_nlri_mrai_destination_based(conn, s, buck, buf+4+la, end);
2660

    
2661
    return buf+4+la+lr;
2662
}
2663

    
2664
static byte *
2665
bgp_create_mp_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2666
{
2667
    /*
2668
     *        2 B        IPv4 Withdrawn Routes Length (zero)
2669
     *        ---        IPv4 Withdrawn Routes NLRI (unused)
2670
     *        2 B        Total Path Attribute Length
2671
     *        1 B        MP_REACH_NLRI hdr - Attribute Flags
2672
     *        1 B        MP_REACH_NLRI hdr - Attribute Type Code
2673
     *        2 B        MP_REACH_NLRI hdr - Length of Attribute Data
2674
     *        2 B        MP_REACH_NLRI data - Address Family Identifier
2675
     *        1 B        MP_REACH_NLRI data - Subsequent Address Family Identifier
2676
     *        1 B        MP_REACH_NLRI data - Length of Next Hop Network Address
2677
     *        var        MP_REACH_NLRI data - Network Address of Next Hop
2678
     *        1 B        MP_REACH_NLRI data - Reserved (zero)
2679
     *        var        MP_REACH_NLRI data - Network Layer Reachability Information
2680
     *        var        Rest of Path Attributes
2681
     *        ---        IPv4 Network Layer Reachability Information (unused)
2682
     */
2683

    
2684
    int lh, lr, la;        /* Lengths of next hop, NLRI and attributes */
2685

    
2686
    /* Begin of MP_REACH_NLRI atribute */
2687
    buf[4] = BAF_OPTIONAL | BAF_EXT_LEN;
2688
    buf[5] = BA_MP_REACH_NLRI;
2689
    put_u16(buf+6, 0);                /* Will be fixed later */
2690
    put_af3(buf+8, s->channel->afi);
2691
    byte *pos = buf+11;
2692

    
2693
    /* Encode attributes to temporary buffer */
2694
    byte *abuf = alloca(MAX_ATTRS_LENGTH);
2695
    la = bgp_encode_attrs(s, buck->eattrs, abuf, abuf + MAX_ATTRS_LENGTH);
2696
    if (la < 0)
2697
    {
2698
        /* Attribute list too long */
2699
        bgp_withdraw_bucket(s->channel, buck);
2700
        return NULL;
2701
    }
2702

    
2703
    /* Encode the next hop */
2704
    lh = bgp_encode_next_hop(s, s->mp_next_hop, pos+1);
2705
    *pos = lh;
2706
    pos += 1+lh;
2707

    
2708
net_addr *n;
2709
    /* Reserved field */
2710
    *pos++ = 0;
2711

    
2712
    /* Encode the NLRI */
2713
    lr = bgp_encode_nlri(s, buck, pos, end - la);
2714
    pos += lr;
2715

    
2716
    /* End of MP_REACH_NLRI atribute, update data length */
2717
    put_u16(buf+6, pos-buf-8);
2718

    
2719
    /* Copy remaining attributes */
2720
    memcpy(pos, abuf, la);
2721
    pos += la;
2722

    
2723
    /* Initial UPDATE fields */
2724
    put_u16(buf+0, 0);
2725
    put_u16(buf+2, pos-buf-4);
2726

    
2727
    return pos;
2728
}
2729

    
2730
#undef MAX_ATTRS_LENGTH
2731

    
2732
/**
2733
 * For updates with withdrow reachability information
2734
 * @param s
2735
 * @param buck
2736
 * @param buf
2737
 * @param end
2738
 * @return
2739
 */
2740
static byte *
2741
bgp_create_ip_unreach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2742
{
2743
    /*
2744
     *        2 B        Withdrawn Routes Length
2745
     *        var        IPv4 Withdrawn Routes NLRI
2746
     *        2 B        Total Path Attribute Length (zero)
2747
     *        ---        Path Attributes (unused)
2748
     *        ---        IPv4 Network Layer Reachability Information (unused)
2749
     */
2750
    uint len = bgp_encode_nlri(s, buck, buf+2, end);
2751

    
2752
    put_u16(buf+0, len);
2753
    put_u16(buf+2+len, 0);
2754

    
2755
    return buf+4+len;
2756
}
2757

    
2758
static byte *
2759
bgp_create_mp_unreach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2760
{
2761
    /*
2762
     *        2 B        Withdrawn Routes Length (zero)
2763
     *        ---        IPv4 Withdrawn Routes NLRI (unused)
2764
     *        2 B        Total Path Attribute Length
2765
     *        1 B        MP_UNREACH_NLRI hdr - Attribute Flags
2766
     *        1 B        MP_UNREACH_NLRI hdr - Attribute Type Code
2767
     *        2 B        MP_UNREACH_NLRI hdr - Length of Attribute Data
2768
     *        2 B        MP_UNREACH_NLRI data - Address Family Identifier
2769
     *        1 B        MP_UNREACH_NLRI data - Subsequent Address Family Identifier
2770
     *        var        MP_UNREACH_NLRI data - Network Layer Reachability Information
2771
     *        ---        IPv4 Network Layer Reachability Information (unused)
2772
     */
2773

    
2774
    uint len = bgp_encode_nlri(s, buck, buf+11, end);
2775

    
2776
    put_u16(buf+0, 0);
2777
    put_u16(buf+2, 7+len);
2778

    
2779
    /* Begin of MP_UNREACH_NLRI atribute */
2780
    buf[4] = BAF_OPTIONAL | BAF_EXT_LEN;
2781
    buf[5] = BA_MP_UNREACH_NLRI;
2782
    put_u16(buf+6, 3+len);
2783
    put_af3(buf+8, s->channel->afi);
2784

    
2785
    return buf+11+len;
2786
}
2787

    
2788
/**
2789
 * Generic function to create an update
2790
 * @param c
2791
 * @param buf
2792
 * @return
2793
 */
2794
static byte *
2795
bgp_create_update(struct bgp_channel *c, byte *buf)
2796
{
2797
    //log(L_INFO "bgp create update");
2798
    struct bgp_proto *p = (void *) c->c.proto;
2799
    struct bgp_bucket *buck;
2800
    byte *end = buf + (bgp_max_packet_length(p->conn) - BGP_HEADER_LENGTH);
2801
    byte *res = NULL;
2802

    
2803
    again: ;
2804

    
2805
    /* Initialize write state */
2806
    struct bgp_write_state s = {
2807
            .proto = p,
2808
            .channel = c,
2809
            .pool = bgp_linpool,
2810
            .as4_session = p->as4_session,
2811
            .add_path = c->add_path_tx,
2812
            .mpls = c->desc->mpls,
2813
    };
2814

    
2815
    /* Try unreachable bucket */
2816
    //If there is information inside this bucket i will send a withdrow
2817
    if ((buck = c->withdraw_bucket) && !EMPTY_LIST(buck->prefixes))
2818
    {
2819
        withdraw_checker = 1;
2820
        res = (c->afi == BGP_AF_IPV4) && !c->ext_next_hop ?
2821
              bgp_create_ip_unreach(&s, buck, buf, end):
2822
              bgp_create_mp_unreach(&s, buck, buf, end);
2823

    
2824
        goto done;
2825
    }
2826

    
2827
    /* Try reachable buckets */
2828
    if (!EMPTY_LIST(c->bucket_queue)) //Il bucket degli indirizzi non è vuoto
2829
    {
2830
        buck = HEAD(c->bucket_queue);
2831

    
2832
        /* Cleanup empty buckets */
2833
        if (EMPTY_LIST(buck->prefixes))
2834
        {
2835
            bgp_free_bucket(c, buck);
2836
            goto again;
2837
        }
2838

    
2839
        /*log(L_INFO "buck prefixes before create ip_reach: ");
2840
        struct bgp_prefix *px;
2841
        WALK_LIST(px, buck->prefixes)
2842
        {
2843
            struct net_addr_ip4 *net = (void *) px->net;
2844
            log(L_INFO
2845
            "Trovata nel bucket rete: %N", &px->net);
2846
        }*/
2847
        res = (c->afi == BGP_AF_IPV4) && !c->ext_next_hop ?
2848
              bgp_create_ip_reach(&s, buck, buf, end):
2849
              bgp_create_mp_reach(&s, buck, buf, end);
2850

    
2851
        if (EMPTY_LIST(buck->prefixes))
2852
            bgp_free_bucket(c, buck);
2853
        else
2854
            bgp_defer_bucket(c, buck);
2855

    
2856
        if (!res)
2857
            goto again;
2858

    
2859
        goto done;
2860
    }
2861

    
2862
    /* No more prefixes to send */
2863
    return NULL;
2864

    
2865
    done:
2866
    BGP_TRACE_RL(&rl_snd_update, D_PACKETS, "Devo inviare un update");
2867
    //TODO spostare queste infor più su, solamente se res non è null
2868
    p->number_of_update_sent += 1;
2869
    total_number_of_update_sent += 1;
2870
    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);
2871
    BGP_TRACE_RL(&rl_snd_update, D_PACKETS, "Sending UPDATE");
2872
    lp_flush(s.pool);
2873

    
2874
    return res;
2875
}
2876

    
2877
/**
2878
 * Generic function to create an update
2879
 * @param c
2880
 * @param buf
2881
 * @return
2882
 */
2883
static byte *
2884
bgp_create_update_mrai_destination_based(struct bgp_conn *conn, struct bgp_channel *c, byte *buf)
2885
{
2886
    struct bgp_proto *p = (void *) c->c.proto;
2887
    struct bgp_bucket *buck;
2888
    byte *end = buf + (bgp_max_packet_length(p->conn) - BGP_HEADER_LENGTH);
2889
    byte *res = NULL;
2890

    
2891
    again: ;
2892
    log(L_INFO "Again");
2893

    
2894
    /* Initialize write state */
2895
    struct bgp_write_state s = {
2896
            .proto = p,
2897
            .channel = c,
2898
            .pool = bgp_linpool,
2899
            .as4_session = p->as4_session,
2900
            .add_path = c->add_path_tx,
2901
            .mpls = c->desc->mpls,
2902
    };
2903

    
2904
    /* Try unreachable bucket */
2905
    //If there is information inside this bucket i will send a withdrow
2906
    if ((buck = c->withdraw_bucket) && !EMPTY_LIST(buck->prefixes))
2907
    {
2908
        withdraw_checker = 1;
2909
        res = (c->afi == BGP_AF_IPV4) && !c->ext_next_hop ?
2910
              bgp_create_ip_unreach(&s, buck, buf, end):
2911
              bgp_create_mp_unreach(&s, buck, buf, end);
2912

    
2913
        log(L_INFO "going in done for unreachable information set");
2914
        goto done;
2915
    }
2916

    
2917
    /* Try reachable buckets */
2918
    log(L_INFO "number of buckets to analize: %d",list_length(&c->bucket_queue));
2919
    if (!EMPTY_LIST(c->bucket_queue)) //Il bucket degli indirizzi non è vuoto
2920
    {
2921
        /* Ciclo sui bucket in quanto alcuni potrebbero essere saltati a causa di indirizzi ritardati da MRAI */
2922
        WALK_LIST(buck, c->bucket_queue)
2923
        {
2924
            /* Cleanup empty buckets */
2925
            if (EMPTY_LIST(buck->prefixes)) {
2926
                bgp_free_bucket(c, buck);
2927
                goto again;
2928
            }
2929

    
2930
            res = (c->afi == BGP_AF_IPV4) && !c->ext_next_hop ?
2931
                  bgp_create_ip_reach_mrai_destination_based(conn, &s, buck, buf, end) :
2932
                  bgp_create_mp_reach(&s, buck, buf, end);
2933

    
2934
            log(L_INFO
2935
            "Res: %d", res);
2936

    
2937
            if (EMPTY_LIST(buck->prefixes))
2938
                bgp_free_bucket(c, buck);
2939

    
2940
            if (!res)
2941
                goto again;
2942

    
2943
            log(L_INFO "prefixAdded: %d", prefixAdded);
2944
            if(prefixAdded > 0) {
2945
                log(L_INFO
2946
                "going in done for reachable information set");
2947
                goto done;
2948
            }
2949
        }
2950
    }
2951

    
2952
    log(L_INFO "Return NULL");
2953
    /* No more prefixes to send */
2954
    return NULL;
2955

    
2956
    done:
2957
    BGP_TRACE_RL(&rl_snd_update, D_PACKETS, "Devo inviare un update");
2958
    p->number_of_update_sent += 1;
2959
    total_number_of_update_sent += 1;
2960
    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);
2961
    BGP_TRACE_RL(&rl_snd_update, D_PACKETS, "Sending UPDATE");
2962
    lp_flush(s.pool);
2963

    
2964
    return res;
2965
}
2966

    
2967
static byte *
2968
bgp_create_ip_end_mark(struct bgp_channel *c UNUSED, byte *buf)
2969
{
2970
    /* Empty update packet */
2971
    put_u32(buf, 0);
2972

    
2973
    return buf+4;
2974
}
2975

    
2976
static byte *
2977
bgp_create_mp_end_mark(struct bgp_channel *c, byte *buf)
2978
{
2979
    put_u16(buf+0, 0);
2980
    put_u16(buf+2, 6);                /* length 4--9 */
2981

    
2982
    /* Empty MP_UNREACH_NLRI atribute */
2983
    buf[4] = BAF_OPTIONAL;
2984
    buf[5] = BA_MP_UNREACH_NLRI;
2985
    buf[6] = 3;                        /* Length 7--9 */
2986
    put_af3(buf+7, c->afi);
2987

    
2988
    return buf+10;
2989
}
2990

    
2991
static byte *
2992
bgp_create_end_mark(struct bgp_channel *c, byte *buf)
2993
{
2994
    struct bgp_proto *p = (void *) c->c.proto;
2995

    
2996
    BGP_TRACE(D_PACKETS, "Sending END-OF-RIB");
2997

    
2998
    return (c->afi == BGP_AF_IPV4) ?
2999
           bgp_create_ip_end_mark(c, buf):
3000
           bgp_create_mp_end_mark(c, buf);
3001
}
3002

    
3003
static inline void
3004
bgp_rx_end_mark(struct bgp_parse_state *s, u32 afi)
3005
{
3006
    struct bgp_proto *p = s->proto;
3007
    struct bgp_channel *c = bgp_get_channel(p, afi);
3008

    
3009
    BGP_TRACE(D_PACKETS, "Got END-OF-RIB");
3010

    
3011
    if (!c)
3012
        DISCARD(BAD_AFI, BGP_AFI(afi), BGP_SAFI(afi));
3013

    
3014
    if (c->load_state == BFS_LOADING)
3015
        c->load_state = BFS_NONE;
3016

    
3017
    if (p->p.gr_recovery)
3018
        channel_graceful_restart_unlock(&c->c);
3019

    
3020
    if (c->gr_active)
3021
        bgp_graceful_restart_done(c);
3022
}
3023

    
3024
/**
3025
 * Generic NLRI decode, to invoke the specific NLRI decoder
3026
 * @param s
3027
 * @param afi
3028
 * @param nlri
3029
 * @param len
3030
 * @param ea
3031
 * @param nh
3032
 * @param nh_len
3033
 */
3034
static inline void
3035
bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_list *ea, byte *nh, uint nh_len)
3036
{
3037
    struct bgp_channel *c = bgp_get_channel(s->proto, afi);
3038
    rta *a = NULL;
3039

    
3040
    if (!c)
3041
        DISCARD(BAD_AFI, BGP_AFI(afi), BGP_SAFI(afi));
3042

    
3043
    s->channel = c;
3044
    s->add_path = c->add_path_rx;
3045
    s->mpls = c->desc->mpls;
3046

    
3047
    s->last_id = 0;
3048
    s->last_src = s->proto->p.main_source;
3049

    
3050
    //TODO gne
3051
    /*if(nh_len == 0){
3052
        //log(L_INFO "Trovato withdraw");
3053
        //withdraw_checker = 1;
3054
    }*/
3055

    
3056
    /*
3057
     * IPv4 BGP and MP-BGP may be used together in one update, therefore we do not
3058
     * add BA_NEXT_HOP in bgp_decode_attrs(), but we add it here independently for
3059
     * IPv4 BGP and MP-BGP. We undo the attribute (and possibly others attached by
3060
     * decode_next_hop hooks) by restoring a->eattrs afterwards.
3061
     */
3062

    
3063
    if (ea)
3064
    {
3065
        a = allocz(RTA_MAX_SIZE);
3066

    
3067
        a->source = RTS_BGP;
3068
        a->scope = SCOPE_UNIVERSE;
3069
        a->from = s->proto->cf->remote_ip;
3070
        a->eattrs = ea;
3071

    
3072
        c->desc->decode_next_hop(s, nh, nh_len, a);
3073
        eattr *e = bgp_find_attr(ea, BA_NEXT_HOP);
3074
        /* Handle withdraw during next hop decoding */
3075
        if (s->err_withdraw)
3076
            a = NULL;
3077
    }
3078

    
3079
    c->desc->decode_nlri(s, nlri, len, a);
3080
    rta_free(s->cached_rta);
3081
    s->cached_rta = NULL;
3082
}
3083

    
3084
static inline struct bgp_channel *
3085
bgp_get_channel_to_send(struct bgp_proto *p, struct bgp_conn *conn)
3086
{
3087
    uint i = conn->last_channel;
3088

    
3089
    /* Try the last channel, but at most several times */
3090
    if ((conn->channels_to_send & (1 << i)) &&
3091
        (conn->last_channel_count < 16))
3092
        goto found;
3093

    
3094
    /* Find channel with non-zero channels_to_send */
3095
    do
3096
    {
3097
        i++;
3098
        if (i >= p->channel_count)
3099
            i = 0;
3100
    }
3101
    while (! (conn->channels_to_send & (1 << i)));
3102

    
3103
    /* Use that channel */
3104
    conn->last_channel = i;
3105
    conn->last_channel_count = 0;
3106

    
3107
    found:
3108
    conn->last_channel_count++;
3109
    return p->channel_map[i];
3110
}
3111

    
3112
static void
3113
bgp_rx_update(struct bgp_conn *conn, byte *pkt, uint len)
3114
{
3115
    char output[50];
3116
    //float tmpLoad = loadComplessivo;
3117
    //snprintf(output, 50, "%f", loadComplessivo);
3118

    
3119
    //withdraw_checker = 0;
3120
    struct bgp_proto *p = conn->bgp;
3121
    snprintf(ASLocale, 12, "%d", p->public_as);
3122

    
3123
    ea_list *ea = NULL;
3124

    
3125
    //rilevatoLoop = 0;
3126
    ASRicezione = p->remote_as;
3127
    BGP_TRACE_RL(&rl_rcv_update, D_PACKETS, "Got UPDATE");
3128

    
3129
    /* Workaround for some BGP implementations that skip initial KEEPALIVE */
3130
    if (conn->state == BS_OPENCONFIRM)
3131
        bgp_conn_enter_established_state(conn);
3132

    
3133
    if (conn->state != BS_ESTABLISHED)
3134
    { bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0); return; }
3135

    
3136
    bgp_start_timer(conn->hold_timer, conn->hold_time);
3137

    
3138
    /* Initialize parse state */
3139
    struct bgp_parse_state s = {
3140
            .proto = p,
3141
            .pool = bgp_linpool,
3142
            .as4_session = p->as4_session,
3143
    };
3144

    
3145
    /* Parse error handler */
3146
    if (setjmp(s.err_jmpbuf))
3147
    {
3148
        bgp_error(conn, 3, s.err_subcode, NULL, 0);
3149
        goto done;
3150
    }
3151

    
3152
    /* Check minimal length */
3153
    if (len < 23)
3154
    { bgp_error(conn, 1, 2, pkt+16, 2); return; }
3155

    
3156
    /* Skip fixed header */
3157
    uint pos = 19;
3158

    
3159
    /*
3160
     *        UPDATE message format
3161
     *
3162
     *        2 B        IPv4 Withdrawn Routes Length
3163
     *        var        IPv4 Withdrawn Routes NLRI
3164
     *        2 B        Total Path Attribute Length
3165
     *        var        Path Attributes
3166
     *        var        IPv4 Reachable Routes NLRI
3167
     */
3168

    
3169
    s.ip_unreach_len = get_u16(pkt + pos);
3170
    s.ip_unreach_nlri = pkt + pos + 2;
3171
    pos += 2 + s.ip_unreach_len;
3172

    
3173
    if (pos + 2 > len)
3174
        bgp_parse_error(&s, 1);
3175

    
3176
    s.attr_len = get_u16(pkt + pos);
3177
    s.attrs = pkt + pos + 2;
3178
    pos += 2 + s.attr_len;
3179

    
3180
    if (pos > len)
3181
        bgp_parse_error(&s, 1);
3182

    
3183
    s.ip_reach_len = len - pos;
3184
    s.ip_reach_nlri = pkt + pos;
3185

    
3186
    //sonoIlNH = 0;
3187
    //numeroNHarrivati = 0.0;
3188
    //loadOutRilevato = 0.0;
3189
    if (s.attr_len)
3190
        ea = bgp_decode_attrs(&s, s.attrs, s.attr_len);
3191
    else
3192
        ea = NULL;
3193

    
3194
    /* Check for End-of-RIB marker */
3195
    if (!s.attr_len && !s.ip_unreach_len && !s.ip_reach_len)
3196
    { bgp_rx_end_mark(&s, BGP_AF_IPV4); goto done; }
3197

    
3198
    /* Check for MP End-of-RIB marker */
3199
    if ((s.attr_len < 8) && !s.ip_unreach_len && !s.ip_reach_len &&
3200
        !s.mp_reach_len && !s.mp_unreach_len && s.mp_unreach_af)
3201
    { bgp_rx_end_mark(&s, s.mp_unreach_af); goto done; }
3202

    
3203
    //char asCKey[12];
3204
    //sprintf(nhCKey, "%d", nhKey);
3205
    //sprintf(asCKey, "%d", ASRicezione);
3206

    
3207
    eattr *e = bgp_find_attr(ea, BA_AS_PATH);
3208
    if (e != NULL) {
3209
        struct adata *ad = (e->type & EAF_EMBEDDED) ? NULL : e->u.ptr;
3210
        as_path_format(ad, buf_as_path, CLI_MSG_SIZE);
3211

    
3212
        //log(L_FATAL
3213
        //"{type: UPDATE_RX, dest: %s, from: %s, nh: %s, as_path: %s}",ipAddrRec, asCKey, nhCKey, buf);
3214
    }
3215

    
3216
    if (s.ip_unreach_len)
3217
        bgp_decode_nlri(&s, BGP_AF_IPV4, s.ip_unreach_nlri, s.ip_unreach_len, NULL, NULL, 0);
3218

    
3219
    if (s.mp_unreach_len)
3220
        bgp_decode_nlri(&s, s.mp_unreach_af, s.mp_unreach_nlri, s.mp_unreach_len, NULL, NULL, 0);
3221

    
3222
    if (s.ip_reach_len)
3223
        bgp_decode_nlri(&s, BGP_AF_IPV4, s.ip_reach_nlri, s.ip_reach_len,
3224
                        ea, s.ip_next_hop_data, s.ip_next_hop_len);
3225

    
3226
    if (s.mp_reach_len)
3227
        bgp_decode_nlri(&s, s.mp_reach_af, s.mp_reach_nlri, s.mp_reach_len,
3228
                        ea, s.mp_next_hop_data, s.mp_next_hop_len);
3229

    
3230
    done:
3231
    rta_free(s.cached_rta);
3232
    lp_flush(s.pool);
3233

    
3234
    //TODO code refactoring
3235
    /*if (tmpLoad != loadComplessivo){
3236
        log(L_INFO "LOAD COMPLESSIVO VARIATO");
3237

3238
        RTable *objFound = map_get(&RTmap, cKey);
3239
        if (objFound == NULL){
3240
            log(L_INFO "objfound è null");
3241
        }
3242
        else if (objFound->P == NULL){
3243
            log(L_INFO "objFound->P è null");
3244
        }
3245
        else if (objFound->C == NULL){
3246
            log(L_INFO "objFound->C è null");
3247
        }
3248
        else if (objFound->n == NULL){
3249
            log(L_INFO "objFound->n è null");
3250
        }
3251
        else if (objFound->rtElem == NULL){
3252
            log(L_INFO "objFound->rtElem è null");
3253
        }
3254
        else if (objFound->ea == NULL){
3255
            log(L_INFO "objFound->ea è null");
3256
        }
3257
        else {
3258
            int tmp = 0;
3259
            int i = 0;
3260
            //bgp_show_proto_info_mine((void *)objFound->P);
3261
            map_iter_t iter3 = map_iter(&objFound->NH);
3262
            const char *key3;
3263
            while ((key3 = map_next(&objFound->NH, &iter3))) {
3264
                i++;
3265
                int *NHmap = map_get(&objFound->NH, key3);
3266
                if (*NHmap == ASRicezione) {
3267
                    tmp = 1;
3268
                }
3269
            }
3270
            if (tmp == 0 && i > 0) {
3271
                //Force RT_notify
3272
                //objFound->P->rt_notify(objFound->P, objFound->C, objFound->n, objFound->rtElem, NULL, objFound->rtElem->attrs->eattrs);
3273
                //ea = objFound->rtElem->attrs->eattrs;
3274
                struct bgp_proto *pr = (void *)objFound->P;
3275
                struct bgp_channel *ch = (void *)objFound->C;
3276
                rte *new = objFound->rtElem;
3277
                net *n = objFound->n;
3278
                struct bgp_bucket *buck;
3279
                struct bgp_prefix *px;
3280
                u32 path;
3281
                ea = bgp_update_attrs(pr, ch, new, ea, bgp_linpool2);
3282
                if(ea) {
3283
                    buck = bgp_get_bucket(ch, ea);
3284
                    path = new->attrs->src->global_id;
3285
                    lp_flush(bgp_linpool2);
3286
                    px = bgp_get_prefix(ch, n->n.addr, ch->add_path_tx ? path : 0);
3287
                    add_tail(&buck->prefixes, &px->buck_node);
3288
                    bgp_schedule_packet(pr->conn, ch, PKT_UPDATE);
3289
                }//
3290
            }
3291
        }
3292
    } else {
3293
        log(L_INFO "Load complessivo invariato");
3294
    }*/
3295

    
3296
    return;
3297
}
3298

    
3299

    
3300
/*
3301
 *        ROUTE-REFRESH
3302
 */
3303

    
3304
static inline byte *
3305
bgp_create_route_refresh(struct bgp_channel *c, byte *buf)
3306
{
3307
    struct bgp_proto *p = (void *) c->c.proto;
3308

    
3309
    BGP_TRACE(D_PACKETS, "Sending ROUTE-REFRESH");
3310

    
3311
    /* Original route refresh request, RFC 2918 */
3312
    put_af4(buf, c->afi);
3313
    buf[2] = BGP_RR_REQUEST;
3314

    
3315
    return buf+4;
3316
}
3317

    
3318
static inline byte *
3319
bgp_create_begin_refresh(struct bgp_channel *c, byte *buf)
3320
{
3321
    struct bgp_proto *p = (void *) c->c.proto;
3322

    
3323
    BGP_TRACE(D_PACKETS, "Sending BEGIN-OF-RR");
3324

    
3325
    /* Demarcation of beginning of route refresh (BoRR), RFC 7313 */
3326
    put_af4(buf, c->afi);
3327
    buf[2] = BGP_RR_BEGIN;
3328

    
3329
    return buf+4;
3330
}
3331

    
3332
static inline byte *
3333
bgp_create_end_refresh(struct bgp_channel *c, byte *buf)
3334
{
3335
    struct bgp_proto *p = (void *) c->c.proto;
3336

    
3337
    BGP_TRACE(D_PACKETS, "Sending END-OF-RR");
3338

    
3339
    /* Demarcation of ending of route refresh (EoRR), RFC 7313 */
3340
    put_af4(buf, c->afi);
3341
    buf[2] = BGP_RR_END;
3342

    
3343
    return buf+4;
3344
}
3345

    
3346
static void
3347
bgp_rx_route_refresh(struct bgp_conn *conn, byte *pkt, uint len)
3348
{
3349
    struct bgp_proto *p = conn->bgp;
3350

    
3351
    if (conn->state != BS_ESTABLISHED)
3352
    { bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0); return; }
3353

    
3354
    if (!conn->local_caps->route_refresh)
3355
    { bgp_error(conn, 1, 3, pkt+18, 1); return; }
3356

    
3357
    if (len < (BGP_HEADER_LENGTH + 4))
3358
    { bgp_error(conn, 1, 2, pkt+16, 2); return; }
3359

    
3360
    if (len > (BGP_HEADER_LENGTH + 4))
3361
    { bgp_error(conn, 7, 1, pkt, MIN(len, 2048)); return; }
3362

    
3363
    struct bgp_channel *c = bgp_get_channel(p, get_af4(pkt+19));
3364
    if (!c)
3365
    {
3366
        log(L_WARN "%s: Got ROUTE-REFRESH subtype %u for AF %u.%u, ignoring",
3367
                p->p.name, pkt[21], get_u16(pkt+19), pkt[22]);
3368
        return;
3369
    }
3370

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

    
3374
    switch (subtype)
3375
    {
3376
        case BGP_RR_REQUEST:
3377
            BGP_TRACE(D_PACKETS, "Got ROUTE-REFRESH");
3378
            channel_request_feeding(&c->c);
3379
            break;
3380

    
3381
        case BGP_RR_BEGIN:
3382
            BGP_TRACE(D_PACKETS, "Got BEGIN-OF-RR");
3383
            bgp_refresh_begin(c);
3384
            break;
3385

    
3386
        case BGP_RR_END:
3387
            BGP_TRACE(D_PACKETS, "Got END-OF-RR");
3388
            bgp_refresh_end(c);
3389
            break;
3390

    
3391
        default:
3392
            log(L_WARN "%s: Got ROUTE-REFRESH message with unknown subtype %u, ignoring",
3393
            p->p.name, subtype);
3394
            break;
3395
    }
3396
}
3397

    
3398
static inline int
3399
bgp_send(struct bgp_conn *conn, uint type, uint len)
3400
{
3401
    sock *sk = conn->sk;
3402
    byte *buf = sk->tbuf;
3403

    
3404
    memset(buf, 0xff, 16);                /* Marker */
3405
    put_u16(buf+16, len);
3406
    buf[18] = type;
3407

    
3408
    return sk_send(sk, len);
3409
}
3410

    
3411
void
3412
bgp_study_delayed_buck(struct bgp_bucket *buck){
3413
    log(L_INFO "bgp_study_delayed_buck");
3414
    if(buck) {
3415
        struct bgp_prefix *px;
3416
        log(L_INFO "Prefix list len: %d", list_length(&buck->prefixes));
3417
        WALK_LIST(px,buck->prefixes){
3418
            px->net->type = 1;
3419
            char time[TM_DATETIME_BUFFER_SIZE];
3420
            tm_format_time(time, &TM_ISO_SHORT_MS, px->sharing_time);
3421
            char share_time[TM_DATETIME_BUFFER_SIZE];
3422
            tm_format_time(share_time, &TM_ISO_SHORT_MS, px->end_mrai);
3423
            log(L_INFO
3424
            "Trovata nel bucket rete: %N con timer: %s verrà condivso dopo: %s", &px->net, time, share_time);
3425
        }
3426
        log(L_INFO
3427
        "no more delayed prefixes");
3428
    }
3429
    else
3430
    {
3431
        log(L_INFO "bucket not initialized");
3432
    }
3433
}
3434

    
3435
/**
3436
 * bgp_fire_tx - transmit packets
3437
 * @conn: connection
3438
 *
3439
 * Whenever the transmit buffers of the underlying TCP connection
3440
 * are free and we have any packets queued for sending, the socket functions
3441
 * call bgp_fire_tx() which takes care of selecting the highest priority packet
3442
 * queued (Notification > Keepalive > Open > Update), assembling its header
3443
 * and body and sending it to the connection.
3444
 */
3445
int
3446
bgp_fire_tx(struct bgp_conn *conn)
3447
{
3448
    struct bgp_proto *p = conn->bgp;
3449
    struct bgp_channel *c;
3450
    byte *buf, *pkt, *end;
3451
    uint s;
3452

    
3453
    if (!conn->sk)
3454
        return 0;
3455

    
3456
    buf = conn->sk->tbuf;
3457
    pkt = buf + BGP_HEADER_LENGTH;
3458
    s = conn->packets_to_send;
3459

    
3460
    if (s & (1 << PKT_SCHEDULE_CLOSE))
3461
    {
3462
        /* We can finally close connection and enter idle state */
3463
        bgp_conn_enter_idle_state(conn);
3464
        return 0;
3465
    }
3466
    if (s & (1 << PKT_NOTIFICATION))
3467
    {
3468
        conn->packets_to_send = 1 << PKT_SCHEDULE_CLOSE;
3469
        end = bgp_create_notification(conn, pkt);
3470
        return bgp_send(conn, PKT_NOTIFICATION, end - buf);
3471
    }
3472
    else if (s & (1 << PKT_KEEPALIVE))
3473
    {
3474
        conn->packets_to_send &= ~(1 << PKT_KEEPALIVE);
3475
        BGP_TRACE(D_PACKETS, "Sending KEEPALIVE");
3476
        bgp_start_timer(conn->keepalive_timer, conn->keepalive_time);
3477
        return bgp_send(conn, PKT_KEEPALIVE, BGP_HEADER_LENGTH);
3478
    }
3479
    else if (s & (1 << PKT_OPEN))
3480
    {
3481
        conn->packets_to_send &= ~(1 << PKT_OPEN);
3482
        end = bgp_create_open(conn, pkt);
3483
        return bgp_send(conn, PKT_OPEN, end - buf);
3484
    }
3485
    else while (conn->channels_to_send &&
3486
                !((s & (1 << PKT_UPDATE)) && tm_active(conn->conn_mrai_timer) && conn->bgp->cf->mrai_type == 0))
3487
        {
3488
            c = bgp_get_channel_to_send(p, conn);
3489
            s = c->packets_to_send;
3490

    
3491
            if (s & (1 << PKT_ROUTE_REFRESH))
3492
            {
3493
                c->packets_to_send &= ~(1 << PKT_ROUTE_REFRESH);
3494
                end = bgp_create_route_refresh(c, pkt);
3495
                return bgp_send(conn, PKT_ROUTE_REFRESH, end - buf);
3496
            }
3497
            else if (s & (1 << PKT_BEGIN_REFRESH))
3498
            {
3499
                /* BoRR is a subtype of RR, but uses separate bit in packets_to_send */
3500
                c->packets_to_send &= ~(1 << PKT_BEGIN_REFRESH);
3501
                end = bgp_create_begin_refresh(c, pkt);
3502
                return bgp_send(conn, PKT_ROUTE_REFRESH, end - buf);
3503
            }
3504
            else if (s & (1 << PKT_UPDATE))
3505
            {
3506
                BGP_TRACE(D_PACKETS, "Ho un pkt di UPDATE da inviare");
3507
                log(L_INFO "Ho un pkt di UPDATE da inviare");
3508
                /* MRAI timer peer-based */
3509
                if(conn->bgp->cf->mrai_type == 0) {
3510
                    if (!tm_active(conn->conn_mrai_timer)) {
3511
                        BGP_TRACE(D_PACKETS, "Il timer MRAI non è attivo");
3512
                        withdraw_checker = 0;
3513
                        end = bgp_create_update(c, pkt);
3514
                        BGP_TRACE(D_PACKETS, "Pacchetto creato");
3515

    
3516
                        if (end) {
3517
                            /* Enable the timer only if the mrai timer is different than 0 */
3518
                            if(withdraw_checker == 0) {
3519
                                log(L_INFO
3520
                                "mrai type: %d", conn->bgp->cf->mrai_type);
3521
                                if (conn->bgp->cf->mrai_time != 0) {
3522
                                    BGP_TRACE(D_PACKETS,
3523
                                              "CONFERMATO PKT UPDATE, avvio il timer considerando un delay di %d ms",
3524
                                              conn->bgp->cf->mrai_time);
3525
                                    bgp_start_ms_timer(conn->conn_mrai_timer, conn->bgp->cf->mrai_time, conn->bgp->cf->mrai_jitter);
3526
                                }
3527
                                log(L_FATAL
3528
                                "{type: UPDATE_TX, dest: %s, to: %d, as_path: %s}", dest_ip, p->remote_as, buf_as_path);
3529
                            }
3530
                            return bgp_send(conn, PKT_UPDATE, end - buf);
3531
                        }
3532

    
3533
                        /* No update to send, perhaps we need to send End-of-RIB or EoRR */
3534
                        c->packets_to_send = 0;
3535
                        conn->channels_to_send &= ~(1 << c->index);
3536

    
3537
                        if (c->feed_state == BFS_LOADED) {
3538
                            c->feed_state = BFS_NONE;
3539
                            end = bgp_create_end_mark(c, pkt);
3540
                            return bgp_send(conn, PKT_UPDATE, end - buf);
3541
                        } else if (c->feed_state == BFS_REFRESHED) {
3542
                            c->feed_state = BFS_NONE;
3543
                            end = bgp_create_end_refresh(c, pkt);
3544
                            return bgp_send(conn, PKT_ROUTE_REFRESH, end - buf);
3545
                        }
3546

    
3547
                        c->packets_to_send = 0;
3548
                        conn->channels_to_send &= ~(1 << c->index);
3549
                    } else {
3550
                        BGP_TRACE(D_PACKETS, "Il timer MRAI è attivo");
3551
                    }
3552
                }
3553
                else { /* MRAI timer destination-based */
3554
                    BGP_TRACE(D_PACKETS, "Il timer MRAI non è attivo");
3555
                    prefixAdded = 0;
3556
                    withdraw_checker = 0;
3557
                    /* Utilizzo di una funzione specifica per la creazione del pacchetto */
3558
                    end = bgp_create_update_mrai_destination_based(conn, c, pkt);
3559
                    BGP_TRACE(D_PACKETS, "Pacchetto creato");
3560
                    bgp_study_delayed_buck(delayed_bucket);
3561

    
3562
                    if(prefixAdded == 0 && withdraw_checker == 0){
3563
                        log(L_INFO "Nessuna rotta aggiunta al pacchetto");
3564
                        return 0;
3565
                    }
3566

    
3567
                    if (end) {
3568
                        if(withdraw_checker == 0) {
3569
                            log(L_INFO
3570
                            "mrai type: %d", conn->bgp->cf->mrai_type);
3571
                            log(L_FATAL
3572
                            "{type: UPDATE_TX, dest: %s, to: %d, as_path: %s}", dest_ip, p->remote_as, buf_as_path);
3573
                        }
3574
                        return bgp_send(conn, PKT_UPDATE, end - buf);
3575
                    }
3576

    
3577
                    /* No update to send, perhaps we need to send End-of-RIB or EoRR */
3578
                    c->packets_to_send = 0;
3579
                    conn->channels_to_send &= ~(1 << c->index);
3580

    
3581
                    if (c->feed_state == BFS_LOADED) {
3582
                        c->feed_state = BFS_NONE;
3583
                        end = bgp_create_end_mark(c, pkt);
3584
                        return bgp_send(conn, PKT_UPDATE, end - buf);
3585
                    } else if (c->feed_state == BFS_REFRESHED) {
3586
                        c->feed_state = BFS_NONE;
3587
                        end = bgp_create_end_refresh(c, pkt);
3588
                        return bgp_send(conn, PKT_ROUTE_REFRESH, end - buf);
3589
                    }
3590

    
3591
                    //TODO this code is repeated twice
3592
                    c->packets_to_send = 0;
3593
                    conn->channels_to_send &= ~(1 << c->index);
3594
                }
3595
            }
3596
            else if (s) {
3597
                bug("Channel packets_to_send: %x", s);
3598

    
3599
                c->packets_to_send = 0;
3600
                conn->channels_to_send &= ~(1 << c->index);
3601
            }
3602
        }
3603

    
3604
    return 0;
3605
}
3606

    
3607
/**
3608
 * bgp_schedule_packet - schedule a packet for transmission
3609
 * @conn: connection
3610
 * @c: channel
3611
 * @type: packet type
3612
 *
3613
 * Schedule a packet of type @type to be sent as soon as possible.
3614
 */
3615
void
3616
bgp_schedule_packet(struct bgp_conn *conn, struct bgp_channel *c, int type)
3617
{
3618
    log(L_INFO "bgp_schedule_packet");
3619
    ASSERT(conn->sk);
3620

    
3621
    DBG("BGP: Scheduling packet type %d\n", type);
3622
    log(L_INFO "BGP: Scheduling packet type %d", type);
3623
    if (c)
3624
    {
3625
        // log(L_INFO "c not null");
3626
        if (! conn->channels_to_send)
3627
        {
3628
            // log(L_INFO "! conn->channels_to_send");
3629
            conn->last_channel = c->index;
3630
            conn->last_channel_count = 0;
3631
        }
3632
        // log(L_INFO "idk 1");
3633
        c->packets_to_send |= 1 << type;
3634
        conn->channels_to_send |= 1 << c->index;
3635
    }
3636
    else {
3637
        conn->packets_to_send |= 1 << type;
3638
        // log(L_INFO "idk 2");
3639
    }
3640

    
3641
    if ((conn->sk->tpos == conn->sk->tbuf) && !ev_active(conn->tx_ev)) {
3642
        // log(L_INFO "evento schedulato!");
3643
        ev_schedule(conn->tx_ev);
3644
    }
3645
}
3646

    
3647
void
3648
bgp_kick_tx(void *vconn)
3649
{
3650
    struct bgp_conn *conn = vconn;
3651
    DBG("BGP: kicking TX\n");
3652

    
3653
    while (bgp_fire_tx(conn) > 0)
3654
        ;
3655
}
3656

    
3657
void
3658
bgp_tx(sock *sk)
3659
{
3660
    struct bgp_conn *conn = sk->data;
3661
    DBG("BGP: TX hook\n");
3662
    while (bgp_fire_tx(conn) > 0)
3663
        ;
3664
}
3665

    
3666

    
3667
static struct {
3668
    byte major, minor;
3669
    byte *msg;
3670
} bgp_msg_table[] = {
3671
        { 1, 0, "Invalid message header" },
3672
        { 1, 1, "Connection not synchronized" },
3673
        { 1, 2, "Bad message length" },
3674
        { 1, 3, "Bad message type" },
3675
        { 2, 0, "Invalid OPEN message" },
3676
        { 2, 1, "Unsupported version number" },
3677
        { 2, 2, "Bad peer AS" },
3678
        { 2, 3, "Bad BGP identifier" },
3679
        { 2, 4, "Unsupported optional parameter" },
3680
        { 2, 5, "Authentication failure" },
3681
        { 2, 6, "Unacceptable hold time" },
3682
        { 2, 7, "Required capability missing" }, /* [RFC5492] */
3683
        { 2, 8, "No supported AFI/SAFI" }, /* This error msg is nonstandard */
3684
        { 3, 0, "Invalid UPDATE message" },
3685
        { 3, 1, "Malformed attribute list" },
3686
        { 3, 2, "Unrecognized well-known attribute" },
3687
        { 3, 3, "Missing mandatory attribute" },
3688
        { 3, 4, "Invalid attribute flags" },
3689
        { 3, 5, "Invalid attribute length" },
3690
        { 3, 6, "Invalid ORIGIN attribute" },
3691
        { 3, 7, "AS routing loop" },                /* Deprecated */
3692
        { 3, 8, "Invalid NEXT_HOP attribute" },
3693
        { 3, 9, "Optional attribute error" },
3694
        { 3, 10, "Invalid network field" },
3695
        { 3, 11, "Malformed AS_PATH" },
3696
        { 4, 0, "Hold timer expired" },
3697
        { 5, 0, "Finite state machine error" }, /* Subcodes are according to [RFC6608] */
3698
        { 5, 1, "Unexpected message in OpenSent state" },
3699
        { 5, 2, "Unexpected message in OpenConfirm state" },
3700
        { 5, 3, "Unexpected message in Established state" },
3701
        { 6, 0, "Cease" }, /* Subcodes are according to [RFC4486] */
3702
        { 6, 1, "Maximum number of prefixes reached" },
3703
        { 6, 2, "Administrative shutdown" },
3704
        { 6, 3, "Peer de-configured" },
3705
        { 6, 4, "Administrative reset" },
3706
        { 6, 5, "Connection rejected" },
3707
        { 6, 6, "Other configuration change" },
3708
        { 6, 7, "Connection collision resolution" },
3709
        { 6, 8, "Out of Resources" },
3710
        { 7, 0, "Invalid ROUTE-REFRESH message" }, /* [RFC7313] */
3711
        { 7, 1, "Invalid ROUTE-REFRESH message length" } /* [RFC7313] */
3712
};
3713

    
3714
/**
3715
 * bgp_error_dsc - return BGP error description
3716
 * @code: BGP error code
3717
 * @subcode: BGP error subcode
3718
 *
3719
 * bgp_error_dsc() returns error description for BGP errors
3720
 * which might be static string or given temporary buffer.
3721
 */
3722
const char *
3723
bgp_error_dsc(uint code, uint subcode)
3724
{
3725
    static char buff[32];
3726
    uint i;
3727

    
3728
    for (i=0; i < ARRAY_SIZE(bgp_msg_table); i++)
3729
        if (bgp_msg_table[i].major == code && bgp_msg_table[i].minor == subcode)
3730
            return bgp_msg_table[i].msg;
3731

    
3732
    bsprintf(buff, "Unknown error %u.%u", code, subcode);
3733
    return buff;
3734
}
3735

    
3736
/* RFC 8203 - shutdown communication message */
3737
static int
3738
bgp_handle_message(struct bgp_proto *p, byte *data, uint len, byte **bp)
3739
{
3740
    byte *msg = data + 1;
3741
    uint msg_len = data[0];
3742
    uint i;
3743

    
3744
    /* Handle zero length message */
3745
    if (msg_len == 0)
3746
        return 1;
3747

    
3748
    /* Handle proper message */
3749
    if ((msg_len > 128) && (msg_len + 1 > len))
3750
        return 0;
3751

    
3752
    /* Some elementary cleanup */
3753
    for (i = 0; i < msg_len; i++)
3754
        if (msg[i] < ' ')
3755
            msg[i] = ' ';
3756

    
3757
    proto_set_message(&p->p, msg, msg_len);
3758
    *bp += bsprintf(*bp, ": \"%s\"", p->p.message);
3759
    return 1;
3760
}
3761

    
3762
void
3763
bgp_log_error(struct bgp_proto *p, u8 class, char *msg, uint code, uint subcode, byte *data, uint len)
3764
{
3765
    byte argbuf[256], *t = argbuf;
3766
    uint i;
3767

    
3768
    /* Don't report Cease messages generated by myself */
3769
    if (code == 6 && class == BE_BGP_TX)
3770
    return;
3771

    
3772
    /* Reset shutdown message */
3773
    if ((code == 6) && ((subcode == 2) || (subcode == 4)))
3774
        proto_set_message(&p->p, NULL, 0);
3775

    
3776
    if (len)
3777
    {
3778
        /* Bad peer AS - we would like to print the AS */
3779
        if ((code == 2) && (subcode == 2) && ((len == 2) || (len == 4)))
3780
        {
3781
            t += bsprintf(t, ": %u", (len == 2) ? get_u16(data) : get_u32(data));
3782
            goto done;
3783
        }
3784

    
3785
        /* RFC 8203 - shutdown communication */
3786
        if (((code == 6) && ((subcode == 2) || (subcode == 4))))
3787
            if (bgp_handle_message(p, data, len, &t))
3788
                goto done;
3789

    
3790
        *t++ = ':';
3791
        *t++ = ' ';
3792
        if (len > 16)
3793
            len = 16;
3794
        for (i=0; i<len; i++)
3795
            t += bsprintf(t, "%02x", data[i]);
3796
    }
3797

    
3798
    done:
3799
    *t = 0;
3800
    const byte *dsc = bgp_error_dsc(code, subcode);
3801
    log(L_REMOTE "%s: %s: %s%s", p->p.name, msg, dsc, argbuf);
3802
}
3803

    
3804
static void
3805
bgp_rx_notification(struct bgp_conn *conn, byte *pkt, uint len)
3806
{
3807
    struct bgp_proto *p = conn->bgp;
3808

    
3809
    if (len < 21)
3810
    { bgp_error(conn, 1, 2, pkt+16, 2); return; }
3811

    
3812
    uint code = pkt[19];
3813
    uint subcode = pkt[20];
3814
    int err = (code != 6);
3815

    
3816
    bgp_log_error(p, BE_BGP_RX, "Received", code, subcode, pkt+21, len-21);
3817
    bgp_store_error(p, conn, BE_BGP_RX, (code << 16) | subcode);
3818

    
3819
    bgp_conn_enter_close_state(conn);
3820
    bgp_schedule_packet(conn, NULL, PKT_SCHEDULE_CLOSE);
3821

    
3822
    if (err)
3823
    {
3824
        bgp_update_startup_delay(p);
3825
        bgp_stop(p, 0, NULL, 0);
3826
    }
3827
}
3828

    
3829
static void
3830
bgp_rx_keepalive(struct bgp_conn *conn)
3831
{
3832
    struct bgp_proto *p = conn->bgp;
3833

    
3834
    BGP_TRACE(D_PACKETS, "Got KEEPALIVE");
3835
    bgp_start_timer(conn->hold_timer, conn->hold_time);
3836

    
3837
    if (conn->state == BS_OPENCONFIRM)
3838
    { bgp_conn_enter_established_state(conn); return; }
3839

    
3840
    if (conn->state != BS_ESTABLISHED)
3841
        bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0);
3842
}
3843

    
3844

    
3845
/**
3846
 * bgp_rx_packet - handle a received packet
3847
 * @conn: BGP connection
3848
 * @pkt: start of the packet
3849
 * @len: packet size
3850
 *
3851
 * bgp_rx_packet() takes a newly received packet and calls the corresponding
3852
 * packet handler according to the packet type.
3853
 */
3854
static void
3855
bgp_rx_packet(struct bgp_conn *conn, byte *pkt, uint len)
3856
{
3857
    byte type = pkt[18];
3858

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

    
3861
    if (conn->bgp->p.mrtdump & MD_MESSAGES)
3862
        mrt_dump_bgp_packet(conn, pkt, len);
3863

    
3864
    switch (type)
3865
    {
3866
        case PKT_OPEN:                return bgp_rx_open(conn, pkt, len);
3867
        case PKT_UPDATE:                return bgp_rx_update(conn, pkt, len);
3868
        case PKT_NOTIFICATION:        return bgp_rx_notification(conn, pkt, len);
3869
        case PKT_KEEPALIVE:                return bgp_rx_keepalive(conn);
3870
        case PKT_ROUTE_REFRESH:        return bgp_rx_route_refresh(conn, pkt, len);
3871
        default:                        bgp_error(conn, 1, 3, pkt+18, 1);
3872
    }
3873
}
3874

    
3875
/**
3876
 * bgp_rx - handle received data
3877
 * @sk: socket
3878
 * @size: amount of data received
3879
 *
3880
 * bgp_rx() is called by the socket layer whenever new data arrive from
3881
 * the underlying TCP connection. It assembles the data fragments to packets,
3882
 * checks their headers and framing and passes complete packets to
3883
 * bgp_rx_packet().
3884
 */
3885
int
3886
bgp_rx(sock *sk, uint size)
3887
{
3888
    struct bgp_conn *conn = sk->data;
3889
    byte *pkt_start = sk->rbuf;
3890
    byte *end = pkt_start + size;
3891
    uint i, len;
3892

    
3893
    DBG("BGP: RX hook: Got %d bytes\n", size);
3894
    while (end >= pkt_start + BGP_HEADER_LENGTH)
3895
    {
3896
        if ((conn->state == BS_CLOSE) || (conn->sk != sk))
3897
            return 0;
3898
        for(i=0; i<16; i++)
3899
            if (pkt_start[i] != 0xff)
3900
            {
3901
                bgp_error(conn, 1, 1, NULL, 0);
3902
                break;
3903
            }
3904
        len = get_u16(pkt_start+16);
3905
        if ((len < BGP_HEADER_LENGTH) || (len > bgp_max_packet_length(conn)))
3906
        {
3907
            bgp_error(conn, 1, 2, pkt_start+16, 2);
3908
            break;
3909
        }
3910
        if (end < pkt_start + len)
3911
            break;
3912
        bgp_rx_packet(conn, pkt_start, len);
3913
        pkt_start += len;
3914
    }
3915
    if (pkt_start != sk->rbuf)
3916
    {
3917
        memmove(sk->rbuf, pkt_start, end - pkt_start);
3918
        sk->rpos = sk->rbuf + (end - pkt_start);
3919
    }
3920
    return 0;
3921
}