Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (122 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
    // TODO Commentato per permettere di leggere il NH
894
    //if (ipa_zero(nh[0]) && ((len != 32) || ipa_zero(nh[1])))
895
    //    WITHDRAW(BAD_NEXT_HOP);
896

    
897
    //TODO prima le righe non erano commentate
898

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

    
913
    /* Forbid next hop with non-matching AF */
914
    if ((ipa_is_ip4(nh[0]) != bgp_channel_is_ipv4(s->channel)) &&
915
        !s->channel->ext_next_hop)
916
        WITHDRAW(BAD_NEXT_HOP);
917

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

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

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

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

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

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

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

    
950
    return len;
951
}
952

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

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

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

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

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

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

    
990
    // XXXX validate next hop
991

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

    
995
    ip4_addr addr4 = get_ip4(data);
996
    ip4_ntop(addr4, next_hop_ip);
997
    //net_addr_ip4 net = NET_ADDR_IP4(ip4_ntoh(addr4), len);
998
    //net_normalize_ip4(&net);
999
    //log(L_FATAL "Address nh ip: %I4", net.prefix);
1000
}
1001

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

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

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

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

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

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

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

    
1033
    return 48;
1034
}
1035

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

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

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

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

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

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

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

    
1077
    // XXXX validate next hop
1078

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

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

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

    
1106
    return;
1107
}
1108

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

    
1117

    
1118
/*
1119
 *        UPDATE
1120
 */
1121

    
1122
static void
1123
bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0)
1124
{
1125
    char local_cKey[12];
1126
    sprintf(local_cKey, "%d%d%d%d", n->data[3], n->data[2], n->data[1], n->data[0]);
1127

    
1128
    //log(L_INFO "BGP_RTE_UPDATE");
1129
    if (path_id != s->last_id)
1130
    {
1131
        //log(L_FATAL "Path id != s->last_id: %lu, %lu", path_id, s->last_id);
1132
        s->last_src = rt_get_source(&s->proto->p, path_id);
1133
        s->last_id = path_id;
1134

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

    
1150
        /* Workaround for rta_lookup() breaking eattrs */
1151
        ea_list *ea = a0->eattrs;
1152
        s->cached_rta = rta_lookup(a0);
1153
        a0->eattrs = ea;
1154
    }
1155

    
1156
    rta *a = rta_clone(s->cached_rta);
1157
    rte *e = rte_get_temp(a);
1158
    e->pflags = 0;
1159
    e->u.bgp.suppressed = 0;
1160
    struct channel *c = &s->channel->c;
1161
    struct proto_stats *stats = &c->stats;
1162

    
1163
    //log(L_INFO "s->channel->c->stats->imp_updates_ignored: %d",stats->imp_updates_ignored);
1164
    //log(L_INFO "s->channel->c->stats->imp_routes: %d",stats->imp_routes);
1165
    //How much updates are ignored
1166
    uint old_imp_updates_ignored = stats->imp_updates_ignored;
1167

    
1168

    
1169
    rte_update2(&s->channel->c, n, e, s->last_src);
1170
    //log(L_INFO "s->channel->c->stats->imp_updates_ignored: %d",stats->imp_updates_ignored);
1171
    //log(L_INFO "s->channel->c->stats->imp_routes: %d",stats->imp_routes);
1172

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

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

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

    
1208
    for (uint i = 0; i < lnum; i++)
1209
    {
1210
        put_u24(*pos, labels[i] << 4);
1211
        ADVANCE(*pos, *size, 3);
1212
    }
1213

    
1214
    /* Add bottom-of-stack flag */
1215
    (*pos)[-1] |= BGP_MPLS_BOS;
1216

    
1217
    *pxlen += 24 * lnum;
1218
}
1219

    
1220
static void
1221
bgp_decode_mpls_labels(struct bgp_parse_state *s, byte **pos, uint *len, uint *pxlen, rta *a)
1222
{
1223
    u32 labels[BGP_MPLS_MAX], label;
1224
    uint lnum = 0;
1225

    
1226
    do {
1227
        if (*pxlen < 24)
1228
            bgp_parse_error(s, 1);
1229

    
1230
        label = get_u24(*pos);
1231
        labels[lnum++] = label >> 4;
1232
        ADVANCE(*pos, *len, 3);
1233
        *pxlen -= 24;
1234

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

    
1241
    if (!a)
1242
        return;
1243

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

    
1251
    /* Overwrite data in the attribute */
1252
    s->mpls_labels->length = 4*lnum;
1253
    memcpy(s->mpls_labels->data, labels, 4*lnum);
1254

    
1255
    /* Update next hop entry in rta */
1256
    bgp_apply_mpls_labels(s, a, labels, lnum);
1257

    
1258
    /* Attributes were changed, invalidate cached entry */
1259
    rta_free(s->cached_rta);
1260
    s->cached_rta = NULL;
1261

    
1262
    return;
1263
}
1264

    
1265
/*
1266
 *        Prefix hash table
1267
 */
1268

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

    
1275
#define PXH_REHASH                bgp_pxh_rehash
1276
#define PXH_PARAMS                /8, *2, 2, 2, 8, 20
1277

    
1278

    
1279
HASH_DEFINE_REHASH_FN(PXH, struct bgp_prefix)
1280

    
1281
static struct bgp_bucket *
1282
bgp_get_delayed_bucket()
1283
{
1284
    if (!delayed_bucket)
1285
    {
1286
        delayed_bucket = mb_allocz(proto_pool, sizeof(struct bgp_bucket));
1287
        init_list(&delayed_bucket->prefixes);
1288
    }
1289

    
1290
    return delayed_bucket;
1291
}
1292

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

    
1306
    log(L_INFO "encode nlri NO mrai");
1307

    
1308
    while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
1309
    {
1310
        struct bgp_prefix *px = HEAD(buck->prefixes);
1311
        struct net_addr_ip4 *net = (void *) px->net;
1312

    
1313
        /* Encode path ID */
1314
        if (s->add_path)
1315
        {
1316
            put_u32(pos, px->path_id);
1317
            ADVANCE(pos, size, 4);
1318
        }
1319

    
1320
        /* Encode prefix length */
1321
        *pos = net->pxlen;
1322
        ADVANCE(pos, size, 1);
1323

    
1324
        /* Encode MPLS labels */
1325
        if (s->mpls)
1326
            bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
1327

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

    
1335
        bgp_free_prefix(s->channel, px);
1336
    }
1337

    
1338
    return pos - buf;
1339
}
1340

    
1341
int
1342
already_in_conn_list(list *connections, struct bgp_conn *conn){
1343
    struct conn_list_node *obj;
1344
    WALK_LIST(obj, *connections){
1345
        if (obj->conn == conn){
1346
            return 1;
1347
        }
1348
    }
1349
    return 0;
1350
}
1351

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

    
1366

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

    
1383
            log(L_INFO
1384
            "Trovata nel bucket rete: %N", &px->net);
1385

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

    
1411
                init_list(&tmp_prefix->connections);
1412

    
1413
                /* Timer settings */
1414
                tmp_prefix->dest_mrai_timer = tm_new_init(proto_pool, dest_mrai_timeout, &tmp_prefix->connections, 0, 0);
1415
                bgp_start_ms_timer(tmp_prefix->dest_mrai_timer, conn->bgp->cf->mrai_time, conn->bgp->cf->mrai_jitter);
1416
                HASH_INSERT2(sent_prefix_hash, PXH, proto_pool, tmp_prefix);
1417

    
1418
                /* Add prefix to the delayed bucket */
1419
                struct bgp_bucket *buck;
1420
                buck = bgp_get_delayed_bucket();
1421
                add_tail(&buck->prefixes, &tmp_prefix->buck_node);
1422

    
1423
                /* Encode path ID */
1424
                if (s->add_path) {
1425
                    put_u32(pos, px->path_id);
1426
                    ADVANCE(pos, size, 4);
1427
                }
1428

    
1429
                /* Encode prefix length */
1430
                *pos = net->pxlen;
1431
                ADVANCE(pos, size, 1);
1432

    
1433
                /* Encode MPLS labels */
1434
                if (s->mpls)
1435
                    bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
1436

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

    
1452
                    /* Timer and tmp_prefix update */
1453
                    tmp_prefix->sharing_time = current_time();
1454
                    tmp_prefix->end_mrai = current_time() + conn->bgp->cf->mrai_time MS;
1455

    
1456
                    tmp_prefix->dest_mrai_timer = tm_new_init(proto_pool, dest_mrai_timeout, &tmp_prefix->connections, 0, 0);
1457
                    bgp_start_ms_timer(tmp_prefix->dest_mrai_timer, conn->bgp->cf->mrai_time, conn->bgp->cf->mrai_jitter);
1458

    
1459
                    /* Encode path ID */
1460
                    if (s->add_path) {
1461
                        put_u32(pos, px->path_id);
1462
                        ADVANCE(pos, size, 4);
1463
                    }
1464

    
1465
                    /* Encode prefix length */
1466
                    *pos = net->pxlen;
1467
                    ADVANCE(pos, size, 1);
1468

    
1469
                    /* Encode MPLS labels */
1470
                    if (s->mpls)
1471
                        bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
1472

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

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

    
1499
                    /* Se la connection non è già in lista allora la aggiungo */
1500
                    if(!already_in_conn_list(&tmp_prefix->connections, conn)) {
1501
                        add_tail(&tmp_prefix->connections, &conn_node->conn_node);
1502
                    }
1503

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

    
1514
    return pos - buf;
1515
}
1516

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

    
1525
    const char *key;
1526
    char output[50];
1527
    map_iter_t iter;
1528
    iter = map_iter(RTmap);
1529

    
1530
    while ((key = map_next(RTmap, &iter))) {
1531
        sprintf(tmpJsonOut, "keyAddress: %s loadin:",key);
1532
        log(L_INFO "%s", tmpJsonOut);
1533
        //jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1534
        //strcat(jsonOut, tmpJsonOut);
1535

    
1536
        RTable *d = map_get(RTmap, key);
1537

    
1538
        //sprintf(tmpJsonOut, "\tInterno: %d,\n\tNH: {\n",d->interno);
1539
        //log(L_INFO "%s", tmpJsonOut);
1540
        //jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1541
        //strcat(jsonOut, tmpJsonOut);
1542

    
1543
        const char *internalKey;
1544
        map_iter_t internIter;
1545
        internIter = map_iter(d->NH);
1546

    
1547
        /*while((internalKey = map_next(d->NH, &internIter))){
1548
            int *nh = map_get(d->NH, internalKey);
1549
            sprintf(tmpJsonOut, "\t\tkeyNH: %s,\n\t\tValue: %d\n",internalKey, *nh);
1550
            log(L_INFO "%s", tmpJsonOut);
1551
            //jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1552
            //strcat(jsonOut, tmpJsonOut);
1553
        }*/
1554

    
1555
        //sprintf(tmpJsonOut, "LoadIn: {");
1556
        //log(L_INFO "%s", tmpJsonOut);
1557
        //jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1558
        //strcat(jsonOut, tmpJsonOut);
1559

    
1560
        internIter = map_iter(d->loadin);
1561
        while ((internalKey = map_next(d->loadin, &internIter))) {
1562
            float *loadIn = map_get(d->loadin, internalKey);
1563
            snprintf(output, 50, "%f", *loadIn);
1564
            sprintf(tmpJsonOut, "key: %s, loadIn: %s",internalKey,output);
1565
            log(L_INFO "%s", tmpJsonOut);
1566
            //jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1567
            //strcat(jsonOut, tmpJsonOut);
1568
        }
1569

    
1570
        //sprintf(tmpJsonOut, "}\n");
1571
        //log(L_INFO "%s", tmpJsonOut);
1572
        //jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1573
        //strcat(jsonOut, tmpJsonOut);
1574
    }
1575

    
1576
    /*sprintf(tmpJsonOut, "AS_LOAD: {\n");
1577
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1578
    strcat(jsonOut, tmpJsonOut);
1579

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

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

1597
    snprintf(output, 50, "%d", total_number_of_update_sent);
1598
    sprintf(tmpJsonOut, "total_number_of_update_sent: %s\n",output);
1599
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1600
    strcat(jsonOut, tmpJsonOut);*/
1601

    
1602
    //The length of the log message is limited, so i have to split the map if the dimension is not enough
1603
    if(strlen(jsonOut) > 980){
1604
        char *jsonOutPartial = malloc(sizeof(char) * 981);
1605
        memcpy(jsonOutPartial, jsonOut, 980);
1606
        free(jsonOutPartial);
1607
    }
1608

    
1609
    //log(L_INFO "\n%s",jsonOut);
1610
    free(tmpJsonOut);
1611
    free(jsonOut);
1612
}
1613

    
1614
/**
1615
 * Function to print the map into the log but with less informations
1616
 */
1617
void statoAttualeDellaMappaMinimal(){
1618
    char *jsonOut = malloc(sizeof(char) * 2);
1619
    char *tmpJsonOut = malloc(sizeof(char) * 150);
1620
    strcpy(jsonOut, "");
1621

    
1622
    char output[50];
1623
    const char *key;
1624
    map_iter_t iter;
1625

    
1626
    ASLoad *ASLoad_element_2 = map_get(&ASLoad_map, ASLocale);
1627
    if(ASLoad_element_2) {
1628
        snprintf(output, 50, "%f", ASLoad_element_2->load);
1629
        log(L_FATAL "{type: AS_LOAD, load: %s}",output);
1630
    }
1631

    
1632
    /*iter = map_iter(&ASLoad_map);
1633
    int i = 0;
1634
    while ((key = map_next(&ASLoad_map, &iter))) {
1635
        ASLoad *ASLoad_element = map_get(&ASLoad_map, key);
1636
        snprintf(output, 50, "%f", ASLoad_element->load);
1637
        if (i == 0) {
1638
            sprintf(tmpJsonOut, "{type: AS_LOAD, loads: (K:%s, L:%s, M:%d)", key, output, ASLoad_element->metrica);
1639
            i++;
1640
        } else {
1641
            sprintf(tmpJsonOut, "|(K:%s, L:%s, M:%d)", key, output, ASLoad_element->metrica);
1642
        }
1643
        jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1644
        strcat(jsonOut, tmpJsonOut);
1645
    }
1646
    sprintf(tmpJsonOut, "}");
1647
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1648
    strcat(jsonOut, tmpJsonOut);*/
1649

    
1650
    /*snprintf(output, 50, "%f", loadComplessivo);
1651
    sprintf(tmpJsonOut, "loadComplessivo: %s,\n",output);
1652
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1653
    strcat(jsonOut, tmpJsonOut);
1654

1655
    snprintf(output, 50, "%d", total_number_of_update_sent);
1656
    sprintf(tmpJsonOut, "total_number_of_update_sent: %s,\n",output);
1657
    jsonOut = (char *) realloc(jsonOut, strlen(jsonOut) + strlen(tmpJsonOut) + 1);
1658
    strcat(jsonOut, tmpJsonOut);*/
1659

    
1660
    /*int size = 900;
1661

1662
    int iterazioni = strlen(jsonOut) / size;
1663
    if(strlen(jsonOut) % size > 0){
1664
        iterazioni++;
1665
    }
1666

1667
    //Split the message i more pieces
1668
    //log(L_FATAL "\nAS_LOAD: {");
1669
    char *jsonOutPartial;
1670
    char *pointerToJsonOutOriginal = jsonOut;
1671
    if(iterazioni > 1) {
1672
        jsonOutPartial = malloc(sizeof(char) * (size+1));
1673
        do {
1674
            memcpy(jsonOutPartial, jsonOut, size);
1675
            jsonOut += size;
1676
            jsonOutPartial[size] = '\0';
1677
            log(L_FATAL "%s", jsonOutPartial);
1678
            memset(jsonOutPartial, 0, sizeof(*jsonOutPartial));
1679
        } while ((strlen(jsonOut) > size));
1680
        if(strlen(jsonOut) > 0)
1681
            log(L_FATAL "%s",jsonOut);
1682
        free(jsonOutPartial);
1683
    } else {
1684
        log(L_FATAL "%s",jsonOut);
1685
    }*/
1686

    
1687
    //log(L_FATAL "\nIterazioni: %d", iterazioni);
1688
    jsonOut = NULL;
1689
    free(tmpJsonOut);
1690
    //free(pointerToJsonOutOriginal);
1691
}
1692

    
1693
static struct as_list_bucket *
1694
bgp_get_as_list_bucket()
1695
{
1696
    if (!as_bucket)
1697
    {
1698
        as_bucket = mb_allocz(proto_pool, sizeof(struct as_list_bucket));
1699
        init_list(&as_bucket->as_list);
1700
    }
1701

    
1702
    return as_bucket;
1703
}
1704

    
1705
/**
1706
 * This is where DPC happens
1707
 * @param s
1708
 * @param pos
1709
 * @param len
1710
 * @param a
1711
 */
1712
static void
1713
bgp_decode_nlri_ip4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
1714
{
1715
    while (len)
1716
    {
1717
        net_addr_ip4 net;
1718
        u32 path_id = 0;
1719

    
1720
        /* Decode path ID */
1721
        if (s->add_path)
1722
        {
1723
            if (len < 5)
1724
                bgp_parse_error(s, 1);
1725

    
1726
            path_id = get_u32(pos);
1727
            ADVANCE(pos, len, 4);
1728
        }
1729

    
1730
        /* Decode prefix length */
1731
        uint l = *pos;
1732
        ADVANCE(pos, len, 1);
1733

    
1734
        if (len < ((l + 7) / 8))
1735
            bgp_parse_error(s, 1);
1736

    
1737
        /* Decode MPLS labels */
1738
        if (s->mpls)
1739
            bgp_decode_mpls_labels(s, &pos, &len, &l, a);
1740

    
1741
        if (l > IP4_MAX_PREFIX_LENGTH)
1742
            bgp_parse_error(s, 10);
1743

    
1744
        /* Decode prefix body */
1745
        ip4_addr addr = IP4_NONE;
1746
        uint b = (l + 7) / 8;
1747
        memcpy(&addr, pos, b);
1748
        ADVANCE(pos, len, b);
1749

    
1750
        net = NET_ADDR_IP4(ip4_ntoh(addr), l);
1751
        net_normalize_ip4(&net);
1752

    
1753
        net_addr *n = (net_addr *) &net;
1754

    
1755
        int keyAdr = n->data[0] + n->data[1] + n->data[2] + n->data[3];
1756
        char asCKey[12];
1757
        char local_cKey[12];
1758
        sprintf(local_cKey, "%d%d%d%d", n->data[3], n->data[2], n->data[1], n->data[0]);
1759
        sprintf(cKey, "%d%d%d%d", n->data[3], n->data[2], n->data[1], n->data[0]);
1760
        //sprintf(nhCKey, "%d", nhKey);
1761
        sprintf(asCKey, "%d", ASRicezione);
1762

    
1763
        RTable *objFound;
1764
        map_iter_t iter;
1765
        const char *key;
1766
        int *NHmap;
1767
        log(L_INFO "local_cKey: %s, nhCKey: %s, asCKey: %s", local_cKey, nhCKey, asCKey);
1768
        statoAttualeDellaMappa();
1769
        //log(L_INFO "{type: UPDATE_RX, dest: %I4, from: %s, nh: %s}", net.prefix, asCKey, nhCKey);
1770

    
1771
        if(withdraw_checker != 0){ //Withdraw section
1772
            //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", local_cKey, asCKey);
1773
            objFound = map_get(RTmap, local_cKey);
1774
            if (objFound) {
1775
                iter = map_iter(objFound->NH);
1776
                while ((key = map_next(objFound->NH, &iter))) {
1777
                    NHmap = map_get(objFound->NH, key);
1778
                    if (*NHmap == ASRicezione) {
1779
                        map_deinit(objFound->NH);
1780
                        map_deinit(objFound->loadin);
1781
                        map_remove(RTmap, local_cKey);
1782
                        break;
1783
                        //iter = map_iter(&objFound->NH);
1784
                    }
1785
                }
1786
            }
1787
        }
1788
        else {
1789
            NhVecchio = 0;
1790
            if(rilevatoLoop != 1){
1791
                // Nessun loop, controllo se la destinazione esiste già nella mappa
1792
                objFound = map_get(RTmap, local_cKey);
1793
                if (objFound) {
1794
                    //Create a copy of the old objFound
1795
                    tmpElem = initRTableElement(n,1);
1796
                    tmpElem.P = objFound->P;
1797
                    tmpElem.C = objFound->C;
1798
                    tmpElem.n = objFound->n;
1799
                    tmpElem.rtElem = objFound->rtElem;
1800
                    tmpElem.primaVolta = objFound->primaVolta;
1801

    
1802
                    // Destinazione già presente nella mappa, aggiungo il nexthop alla lista dei nexthop
1803
                    NHmap = map_get(objFound->NH, nhCKey);
1804
                    if (NHmap) {
1805
                        log(L_INFO "NH già presente nella lista, lo lascio");
1806
                        NhVecchio = 1;
1807
                        objFound->primaVolta = 1;
1808
                    } else {
1809
                        log(L_INFO "NH non trovato nella mappa, lo aggiungo");
1810
                        if(map_set(objFound->NH, &nhCKey[0], ASRicezione) != 0){
1811
                            log(L_INFO "Elemento non aggiunto alla mappa, ERROR");
1812
                        }
1813
                    }
1814
                } else {
1815
                    log(L_INFO "Destinazione non trovata, aggiungo la destinazione ed il nexthop alla mappa dei nexthop");
1816
                    RTable rtElem = initRTableElement(n,1);
1817
                    if(map_set(RTmap, &local_cKey[0], rtElem) == 0){
1818
                        log(L_INFO "Elemento aggiunto alla mappa");
1819
                        objFound = map_get(RTmap, local_cKey);
1820
                        map_set(&ExternalDestinationMap, &local_cKey[0], 1);
1821
                        log(L_INFO "Aggiungo il nh per questa nuova destinazione");
1822
                        if(map_set(objFound->NH, &nhCKey[0], ASRicezione) != 0){
1823
                            log(L_INFO "Elemento non aggiunto alla mappa, ERROR");
1824
                        }
1825
                        objFound->primaVolta = 1;
1826
                    }
1827
                }
1828
            }
1829

    
1830
            /*Manage load contributes*/
1831
            char output[50];
1832
            if(sonoIlNH == 1){
1833
                log(L_INFO "Io sono tra i NH del mittente, local_cKey: %s", local_cKey);
1834
                objFound = map_get(RTmap, local_cKey);
1835
                if(objFound != NULL) {
1836
                    if (objFound->interno != 0) { //Se io sono origine e NH allora non aggiungo niente, non ho carico in ingresso per le mie stesse destinazioni
1837
                        float *LoadInmap = map_get(objFound->loadin, asCKey);
1838
                        if (LoadInmap) {
1839
                            snprintf(output, 50, "%f", loadOutRilevato);
1840
                            log(L_INFO "Aggiorno il valore loadIn per questo NH, loadOutRilevato: %s NNH: %d", output, numeroNHarrivati);
1841
                            *LoadInmap = loadOutRilevato / (numeroNHarrivati * 1.0);
1842
                            snprintf(output, 50, "%f", *LoadInmap);
1843
                            log(L_INFO "Nuovo valore: %s", output);
1844
                        } else {
1845
                            snprintf(output, 50, "%f", loadOutRilevato);
1846
                            log(L_INFO "LoadIn non trovato nella mappa, lo aggiungo key: %s, loadOutRilevato: %s NNH: %d", asCKey, output, numeroNHarrivati);
1847
                            float valoreLoadIn = loadOutRilevato / (numeroNHarrivati * 1.0);
1848
                            if (map_set(objFound->loadin, &asCKey[0], valoreLoadIn) != 0) {
1849
                                log(L_INFO "Elemento NON aggiunto alla mappa ERROR");
1850
                            }
1851
                        }
1852
                    }
1853
                }
1854
            } else {
1855
                log(L_INFO "Io NON sono tra i NH del mittente, rimuovo leventuale loadin");
1856
                objFound = map_get(RTmap, local_cKey);
1857
                if(objFound != NULL) {
1858
                    float *LoadI = map_get(objFound->loadin, asCKey);
1859
                    if(LoadI != NULL) {
1860
                        char output_tmp[50];
1861
                        snprintf(output_tmp, 50, "%f", *LoadI);
1862
                        log(L_INFO
1863
                        "con local_ckey: %s e asCkey: %s ho un loadin di: %f da rimuovere", output_tmp);
1864
                        map_remove(objFound->loadin, asCKey);
1865
                    }
1866
                }
1867
            }
1868
        }
1869

    
1870
        loadComplessivo = 0;
1871

    
1872
        // Load accumulation
1873
        iter = map_iter(RTmap);
1874
        log(L_INFO "Load accumulation");
1875
        int count_rtable = 0;
1876
        int count_loadin = 0;
1877
        while ((key = map_next(RTmap, &iter))) {
1878
            RTable *d = map_get(RTmap, key);
1879
            if(d != NULL) {
1880
                count_rtable++;
1881
                const char *key4;
1882
                map_iter_t iter4 = map_iter(d->loadin);
1883
                while ((key4 = map_next(d->loadin, &iter4))) {
1884
                    count_loadin++;
1885
                    float *loadIn = map_get(d->loadin, key4);
1886
                    if (loadIn != NULL) {
1887
                        loadComplessivo += *loadIn;
1888
                    }
1889
                }
1890
            }
1891
        }
1892
        char output_loadComplessivo[50];
1893
        snprintf(output_loadComplessivo, 50, "%f", loadComplessivo);
1894
        log(L_INFO "after load accumulation: count_rtable %d, count_loadin %d, loadComplessivo %s", count_rtable, count_loadin, output_loadComplessivo);
1895

    
1896
        //Repropagation information
1897
        ASLoad *ASLoad_element = map_get(&ASLoad_map, ASLocale);
1898
        if (ASLoad_element) {
1899
            log(L_INFO "AS_Load element exists");
1900
            if (ASLoad_element->load != loadComplessivo) { // The local AS have some new metrics to annunce
1901
                ASLoad_element->load = loadComplessivo;
1902
                log(L_INFO "The AS load has changed");
1903
                ASLoad_element->metrica += 1;
1904

    
1905
                statoAttualeDellaMappaMinimal();
1906
                //statoAttualeDellaMappa();
1907
                map_iter_t iter = map_iter(&ASLoad_element->remoteMap);
1908
                while ((key = map_next(&ASLoad_element->remoteMap, &iter))) {
1909
                    //log(L_INFO "key: %s, size: %d", key, sizeof(key));
1910
                    map_remove(&ASLoad_element->remoteMap, key);
1911
                    iter = map_iter(&ASLoad_element->remoteMap);
1912
                }
1913
            }
1914
        }
1915

    
1916
        //struct as_list_bucket *buck;
1917
        //buck = bgp_get_as_list_bucket();
1918
        //struct as_obj_node *tmp_as_obj = HASH_FIND(as_list_hash, PXH, px->net, px->path_id, px->hash);
1919
        //tmp_prefix = mb_alloc(proto_pool, sizeof(struct bgp_prefix) + px->net->length);
1920

    
1921
        //statoAttualeDellaMappaMinimal();
1922

    
1923
        struct channel *c = &s->channel->c;
1924
        struct proto_stats *stats = &c->stats;
1925
        uint old_imp_updates_ignored = stats->imp_updates_ignored;
1926
        uint old_imp_updates_accepted = stats->imp_updates_accepted;
1927
        uint old_imp_updates_best_substitution = stats->imp_updates_best_substitution;
1928
        uint old_imp_updates_removed_route = stats->imp_updates_removed_route;
1929

    
1930
        struct network *old_net = net_get(c->table, (net_addr *) &net);
1931
        rte *old_best = old_net->routes;
1932
        sprintf(buf_old_best_as_path, "NONE");
1933
        if (old_best != NULL) {
1934
            struct rta *old_attrs = old_best->attrs;
1935
            if (old_attrs != NULL) {
1936
                struct ea_list *old_eattrs = old_attrs->eattrs;
1937
                eattr *e_attr_old = bgp_find_attr(old_eattrs, BA_AS_PATH);
1938
                if (e_attr_old != NULL) {
1939
                    struct adata *ad = (e_attr_old->type & EAF_EMBEDDED) ? NULL : e_attr_old->u.ptr;
1940
                    as_path_format(ad, buf_old_best_as_path, CLI_MSG_SIZE);
1941
                }
1942
            }
1943
        }
1944

    
1945
        bgp_rte_update(s, (net_addr *) &net, path_id, a); //call to the function that update the RT
1946
        //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,
1947
        //        old_imp_updates_accepted, stats->imp_updates_accepted, old_imp_updates_best_substitution, stats->imp_updates_best_substitution);
1948
        struct network *new_net = net_get(c->table, (net_addr *) &net);
1949
        rte *mew_best = new_net->routes;
1950
        sprintf(buf_new_best_as_path, "NONE");
1951
        if (mew_best != NULL) {
1952
            struct rta *new_attrs = mew_best->attrs;
1953
            if (new_attrs != NULL) {
1954
                struct ea_list *new_eattrs = new_attrs->eattrs;
1955
                eattr *e_attr_new = bgp_find_attr(new_eattrs, BA_AS_PATH);
1956
                if (e_attr_new != NULL) {
1957
                    struct adata *ad = (e_attr_new->type & EAF_EMBEDDED) ? NULL : e_attr_new->u.ptr;
1958
                    as_path_format(ad, buf_new_best_as_path, CLI_MSG_SIZE);
1959
                }
1960
            }
1961
        }
1962

    
1963
        if(stats->imp_updates_ignored > old_imp_updates_ignored){
1964
            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}",
1965
                    net.prefix,
1966
                    asCKey,
1967
                    next_hop_ip,
1968
                    buf_as_path,
1969
                    buf_old_best_as_path,
1970
                    buf_new_best_as_path);
1971
        } else if (stats->imp_updates_accepted > old_imp_updates_accepted){
1972
            if (stats->imp_updates_best_substitution > old_imp_updates_best_substitution){
1973
                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}",
1974
                        net.prefix,
1975
                        asCKey,
1976
                        next_hop_ip,
1977
                        buf_as_path,
1978
                        buf_old_best_as_path,
1979
                        buf_new_best_as_path);
1980
            } else {
1981
                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}",
1982
                        net.prefix,
1983
                        asCKey,
1984
                        next_hop_ip,
1985
                        buf_as_path,
1986
                        buf_old_best_as_path,
1987
                        buf_new_best_as_path);
1988
            }
1989
        } else {
1990
            if(stats->imp_updates_removed_route > old_imp_updates_removed_route){
1991
                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}",
1992
                        net.prefix,
1993
                        asCKey,
1994
                        next_hop_ip,
1995
                        buf_as_path,
1996
                        buf_old_best_as_path,
1997
                        buf_new_best_as_path);
1998
            }
1999
        }
2000
    }
2001
}
2002

    
2003

    
2004
//TODO do it for ipv6? :thinking:
2005
static uint
2006
bgp_encode_nlri_ip6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
2007
{
2008
    byte *pos = buf;
2009

    
2010
    while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
2011
    {
2012
        struct bgp_prefix *px = HEAD(buck->prefixes);
2013
        struct net_addr_ip6 *net = (void *) px->net;
2014

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

    
2022
        /* Encode prefix length */
2023
        *pos = net->pxlen;
2024
        ADVANCE(pos, size, 1);
2025

    
2026
        /* Encode MPLS labels */
2027
        if (s->mpls)
2028
            bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
2029

    
2030
        /* Encode prefix body */
2031
        ip6_addr a = ip6_hton(net->prefix);
2032
        uint b = (net->pxlen + 7) / 8;
2033
        memcpy(pos, &a, b);
2034
        ADVANCE(pos, size, b);
2035

    
2036
        bgp_free_prefix(s->channel, px);
2037
    }
2038

    
2039
    return pos - buf;
2040
}
2041

    
2042
static void
2043
bgp_decode_nlri_ip6(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
2044
{
2045
    while (len)
2046
    {
2047
        net_addr_ip6 net;
2048
        u32 path_id = 0;
2049

    
2050
        /* Decode path ID */
2051
        if (s->add_path)
2052
        {
2053
            if (len < 5)
2054
                bgp_parse_error(s, 1);
2055

    
2056
            path_id = get_u32(pos);
2057
            ADVANCE(pos, len, 4);
2058
        }
2059

    
2060
        /* Decode prefix length */
2061
        uint l = *pos;
2062
        ADVANCE(pos, len, 1);
2063

    
2064
        if (len < ((l + 7) / 8))
2065
            bgp_parse_error(s, 1);
2066

    
2067
        /* Decode MPLS labels */
2068
        if (s->mpls)
2069
            bgp_decode_mpls_labels(s, &pos, &len, &l, a);
2070

    
2071
        if (l > IP6_MAX_PREFIX_LENGTH)
2072
            bgp_parse_error(s, 10);
2073

    
2074
        /* Decode prefix body */
2075
        ip6_addr addr = IP6_NONE;
2076
        uint b = (l + 7) / 8;
2077
        memcpy(&addr, pos, b);
2078
        ADVANCE(pos, len, b);
2079

    
2080
        net = NET_ADDR_IP6(ip6_ntoh(addr), l);
2081
        net_normalize_ip6(&net);
2082

    
2083
        // XXXX validate prefix
2084

    
2085
        bgp_rte_update(s, (net_addr *) &net, path_id, a);
2086
    }
2087
}
2088

    
2089
static uint
2090
bgp_encode_nlri_vpn4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
2091
{
2092
    byte *pos = buf;
2093

    
2094
    while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
2095
    {
2096
        struct bgp_prefix *px = HEAD(buck->prefixes);
2097
        struct net_addr_vpn4 *net = (void *) px->net;
2098

    
2099
        /* Encode path ID */
2100
        if (s->add_path)
2101
        {
2102
            put_u32(pos, px->path_id);
2103
            ADVANCE(pos, size, 4);
2104
        }
2105

    
2106
        /* Encode prefix length */
2107
        *pos = 64 + net->pxlen;
2108
        ADVANCE(pos, size, 1);
2109

    
2110
        /* Encode MPLS labels */
2111
        if (s->mpls)
2112
            bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
2113

    
2114
        /* Encode route distinguisher */
2115
        put_u64(pos, net->rd);
2116
        ADVANCE(pos, size, 8);
2117

    
2118
        /* Encode prefix body */
2119
        ip4_addr a = ip4_hton(net->prefix);
2120
        uint b = (net->pxlen + 7) / 8;
2121
        memcpy(pos, &a, b);
2122
        ADVANCE(pos, size, b);
2123

    
2124
        bgp_free_prefix(s->channel, px);
2125
    }
2126

    
2127
    return pos - buf;
2128
}
2129

    
2130
static void
2131
bgp_decode_nlri_vpn4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
2132
{
2133
    while (len)
2134
    {
2135
        net_addr_vpn4 net;
2136
        u32 path_id = 0;
2137

    
2138
        /* Decode path ID */
2139
        if (s->add_path)
2140
        {
2141
            if (len < 5)
2142
                bgp_parse_error(s, 1);
2143

    
2144
            path_id = get_u32(pos);
2145
            ADVANCE(pos, len, 4);
2146
        }
2147

    
2148
        /* Decode prefix length */
2149
        uint l = *pos;
2150
        ADVANCE(pos, len, 1);
2151

    
2152
        if (len < ((l + 7) / 8))
2153
            bgp_parse_error(s, 1);
2154

    
2155
        /* Decode MPLS labels */
2156
        if (s->mpls)
2157
            bgp_decode_mpls_labels(s, &pos, &len, &l, a);
2158

    
2159
        /* Decode route distinguisher */
2160
        if (l < 64)
2161
            bgp_parse_error(s, 1);
2162

    
2163
        u64 rd = get_u64(pos);
2164
        ADVANCE(pos, len, 8);
2165
        l -= 64;
2166

    
2167
        if (l > IP4_MAX_PREFIX_LENGTH)
2168
            bgp_parse_error(s, 10);
2169

    
2170
        /* Decode prefix body */
2171
        ip4_addr addr = IP4_NONE;
2172
        uint b = (l + 7) / 8;
2173
        memcpy(&addr, pos, b);
2174
        ADVANCE(pos, len, b);
2175

    
2176
        net = NET_ADDR_VPN4(ip4_ntoh(addr), l, rd);
2177
        net_normalize_vpn4(&net);
2178

    
2179
        // XXXX validate prefix
2180

    
2181
        bgp_rte_update(s, (net_addr *) &net, path_id, a);
2182
    }
2183
}
2184

    
2185
static uint
2186
bgp_encode_nlri_vpn6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
2187
{
2188
    byte *pos = buf;
2189

    
2190
    while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
2191
    {
2192
        struct bgp_prefix *px = HEAD(buck->prefixes);
2193
        struct net_addr_vpn6 *net = (void *) px->net;
2194

    
2195
        /* Encode path ID */
2196
        if (s->add_path)
2197
        {
2198
            put_u32(pos, px->path_id);
2199
            ADVANCE(pos, size, 4);
2200
        }
2201

    
2202
        /* Encode prefix length */
2203
        *pos = 64 + net->pxlen;
2204
        ADVANCE(pos, size, 1);
2205

    
2206
        /* Encode MPLS labels */
2207
        if (s->mpls)
2208
            bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
2209

    
2210
        /* Encode route distinguisher */
2211
        put_u64(pos, net->rd);
2212
        ADVANCE(pos, size, 8);
2213

    
2214
        /* Encode prefix body */
2215
        ip6_addr a = ip6_hton(net->prefix);
2216
        uint b = (net->pxlen + 7) / 8;
2217
        memcpy(pos, &a, b);
2218
        ADVANCE(pos, size, b);
2219

    
2220
        bgp_free_prefix(s->channel, px);
2221
    }
2222

    
2223
    return pos - buf;
2224
}
2225

    
2226
static void
2227
bgp_decode_nlri_vpn6(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
2228
{
2229
    while (len)
2230
    {
2231
        net_addr_vpn6 net;
2232
        u32 path_id = 0;
2233

    
2234
        /* Decode path ID */
2235
        if (s->add_path)
2236
        {
2237
            if (len < 5)
2238
                bgp_parse_error(s, 1);
2239

    
2240
            path_id = get_u32(pos);
2241
            ADVANCE(pos, len, 4);
2242
        }
2243

    
2244
        /* Decode prefix length */
2245
        uint l = *pos;
2246
        ADVANCE(pos, len, 1);
2247

    
2248
        if (len < ((l + 7) / 8))
2249
            bgp_parse_error(s, 1);
2250

    
2251
        /* Decode MPLS labels */
2252
        if (s->mpls)
2253
            bgp_decode_mpls_labels(s, &pos, &len, &l, a);
2254

    
2255
        /* Decode route distinguisher */
2256
        if (l < 64)
2257
            bgp_parse_error(s, 1);
2258

    
2259
        u64 rd = get_u64(pos);
2260
        ADVANCE(pos, len, 8);
2261
        l -= 64;
2262

    
2263
        if (l > IP6_MAX_PREFIX_LENGTH)
2264
            bgp_parse_error(s, 10);
2265

    
2266
        /* Decode prefix body */
2267
        ip6_addr addr = IP6_NONE;
2268
        uint b = (l + 7) / 8;
2269
        memcpy(&addr, pos, b);
2270
        ADVANCE(pos, len, b);
2271

    
2272
        net = NET_ADDR_VPN6(ip6_ntoh(addr), l, rd);
2273
        net_normalize_vpn6(&net);
2274

    
2275
        // XXXX validate prefix
2276

    
2277
        bgp_rte_update(s, (net_addr *) &net, path_id, a);
2278
    }
2279
}
2280

    
2281
static uint
2282
bgp_encode_nlri_flow4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
2283
{
2284
    byte *pos = buf;
2285

    
2286
    while (!EMPTY_LIST(buck->prefixes) && (size >= 4))
2287
    {
2288
        struct bgp_prefix *px = HEAD(buck->prefixes);
2289
        struct net_addr_flow4 *net = (void *) px->net;
2290
        uint flen = net->length - sizeof(net_addr_flow4);
2291

    
2292
        /* Encode path ID */
2293
        if (s->add_path)
2294
        {
2295
            put_u32(pos, px->path_id);
2296
            ADVANCE(pos, size, 4);
2297
        }
2298

    
2299
        if (flen > size)
2300
            break;
2301

    
2302
        /* Copy whole flow data including length */
2303
        memcpy(pos, net->data, flen);
2304
        ADVANCE(pos, size, flen);
2305

    
2306
        bgp_free_prefix(s->channel, px);
2307
    }
2308

    
2309
    return pos - buf;
2310
}
2311

    
2312
static void
2313
bgp_decode_nlri_flow4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
2314
{
2315
    while (len)
2316
    {
2317
        u32 path_id = 0;
2318

    
2319
        /* Decode path ID */
2320
        if (s->add_path)
2321
        {
2322
            if (len < 4)
2323
                bgp_parse_error(s, 1);
2324

    
2325
            path_id = get_u32(pos);
2326
            ADVANCE(pos, len, 4);
2327
        }
2328

    
2329
        if (len < 2)
2330
            bgp_parse_error(s, 1);
2331

    
2332
        /* Decode flow length */
2333
        uint hlen = flow_hdr_length(pos);
2334
        uint dlen = flow_read_length(pos);
2335
        uint flen = hlen + dlen;
2336
        byte *data = pos + hlen;
2337

    
2338
        if (len < flen)
2339
            bgp_parse_error(s, 1);
2340

    
2341
        /* Validate flow data */
2342
        enum flow_validated_state r = flow4_validate(data, dlen);
2343
        if (r != FLOW_ST_VALID)
2344
        {
2345
            log(L_REMOTE "%s: Invalid flow route: %s", s->proto->p.name, flow_validated_state_str(r));
2346
            bgp_parse_error(s, 1);
2347
        }
2348

    
2349
        if (data[0] != FLOW_TYPE_DST_PREFIX)
2350
        {
2351
            log(L_REMOTE "%s: No dst prefix at first pos", s->proto->p.name);
2352
            bgp_parse_error(s, 1);
2353
        }
2354

    
2355
        /* Decode dst prefix */
2356
        ip4_addr px = IP4_NONE;
2357
        uint pxlen = data[1];
2358

    
2359
        // FIXME: Use some generic function
2360
        memcpy(&px, data+2, BYTES(pxlen));
2361
        px = ip4_and(ip4_ntoh(px), ip4_mkmask(pxlen));
2362

    
2363
        /* Prepare the flow */
2364
        net_addr *n = alloca(sizeof(struct net_addr_flow4) + flen);
2365
        net_fill_flow4(n, px, pxlen, pos, flen);
2366
        ADVANCE(pos, len, flen);
2367

    
2368
        bgp_rte_update(s, n, path_id, a);
2369
    }
2370
}
2371

    
2372
static uint
2373
bgp_encode_nlri_flow6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
2374
{
2375
    byte *pos = buf;
2376

    
2377
    while (!EMPTY_LIST(buck->prefixes) && (size >= 4))
2378
    {
2379
        struct bgp_prefix *px = HEAD(buck->prefixes);
2380
        struct net_addr_flow6 *net = (void *) px->net;
2381
        uint flen = net->length - sizeof(net_addr_flow6);
2382

    
2383
        /* Encode path ID */
2384
        if (s->add_path)
2385
        {
2386
            put_u32(pos, px->path_id);
2387
            ADVANCE(pos, size, 4);
2388
        }
2389

    
2390
        if (flen > size)
2391
            break;
2392

    
2393
        /* Copy whole flow data including length */
2394
        memcpy(pos, net->data, flen);
2395
        ADVANCE(pos, size, flen);
2396

    
2397
        bgp_free_prefix(s->channel, px);
2398
    }
2399

    
2400
    return pos - buf;
2401
}
2402

    
2403
static void
2404
bgp_decode_nlri_flow6(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
2405
{
2406
    while (len)
2407
    {
2408
        u32 path_id = 0;
2409

    
2410
        /* Decode path ID */
2411
        if (s->add_path)
2412
        {
2413
            if (len < 4)
2414
                bgp_parse_error(s, 1);
2415

    
2416
            path_id = get_u32(pos);
2417
            ADVANCE(pos, len, 4);
2418
        }
2419

    
2420
        if (len < 2)
2421
            bgp_parse_error(s, 1);
2422

    
2423
        /* Decode flow length */
2424
        uint hlen = flow_hdr_length(pos);
2425
        uint dlen = flow_read_length(pos);
2426
        uint flen = hlen + dlen;
2427
        byte *data = pos + hlen;
2428

    
2429
        if (len < flen)
2430
            bgp_parse_error(s, 1);
2431

    
2432
        /* Validate flow data */
2433
        enum flow_validated_state r = flow6_validate(data, dlen);
2434
        if (r != FLOW_ST_VALID)
2435
        {
2436
            log(L_REMOTE "%s: Invalid flow route: %s", s->proto->p.name, flow_validated_state_str(r));
2437
            bgp_parse_error(s, 1);
2438
        }
2439

    
2440
        if (data[0] != FLOW_TYPE_DST_PREFIX)
2441
        {
2442
            log(L_REMOTE "%s: No dst prefix at first pos", s->proto->p.name);
2443
            bgp_parse_error(s, 1);
2444
        }
2445

    
2446
        /* Decode dst prefix */
2447
        ip6_addr px = IP6_NONE;
2448
        uint pxlen = data[1];
2449

    
2450
        // FIXME: Use some generic function
2451
        memcpy(&px, data+2, BYTES(pxlen));
2452
        px = ip6_and(ip6_ntoh(px), ip6_mkmask(pxlen));
2453

    
2454
        /* Prepare the flow */
2455
        net_addr *n = alloca(sizeof(struct net_addr_flow6) + flen);
2456
        net_fill_flow6(n, px, pxlen, pos, flen);
2457
        ADVANCE(pos, len, flen);
2458

    
2459
        bgp_rte_update(s, n, path_id, a);
2460
    }
2461
}
2462

    
2463
//This data structure define what function to use, it's used by external libraries
2464
static const struct bgp_af_desc bgp_af_table[] = {
2465
        {
2466
                .afi = BGP_AF_IPV4,
2467
                .net = NET_IP4,
2468
                .name = "ipv4",
2469
                .encode_nlri = bgp_encode_nlri_ip4,
2470
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2471
                .decode_nlri = bgp_decode_nlri_ip4,
2472
                .encode_next_hop = bgp_encode_next_hop_ip,
2473
                .decode_next_hop = bgp_decode_next_hop_ip,
2474
                .update_next_hop = bgp_update_next_hop_ip,
2475
        },
2476
        {
2477
                .afi = BGP_AF_IPV4_MC,
2478
                .net = NET_IP4,
2479
                .name = "ipv4-mc",
2480
                .encode_nlri = bgp_encode_nlri_ip4,
2481
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2482
                .decode_nlri = bgp_decode_nlri_ip4,
2483
                .encode_next_hop = bgp_encode_next_hop_ip,
2484
                .decode_next_hop = bgp_decode_next_hop_ip,
2485
                .update_next_hop = bgp_update_next_hop_ip,
2486
        },
2487
        {
2488
                .afi = BGP_AF_IPV4_MPLS,
2489
                .net = NET_IP4,
2490
                .mpls = 1,
2491
                .name = "ipv4-mpls",
2492
                .encode_nlri = bgp_encode_nlri_ip4,
2493
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2494
                .decode_nlri = bgp_decode_nlri_ip4,
2495
                .encode_next_hop = bgp_encode_next_hop_ip,
2496
                .decode_next_hop = bgp_decode_next_hop_ip,
2497
                .update_next_hop = bgp_update_next_hop_ip,
2498
        },
2499
        {
2500
                .afi = BGP_AF_IPV6,
2501
                .net = NET_IP6,
2502
                .name = "ipv6",
2503
                .encode_nlri = bgp_encode_nlri_ip6,
2504
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2505
                .decode_nlri = bgp_decode_nlri_ip6,
2506
                .encode_next_hop = bgp_encode_next_hop_ip,
2507
                .decode_next_hop = bgp_decode_next_hop_ip,
2508
                .update_next_hop = bgp_update_next_hop_ip,
2509
        },
2510
        {
2511
                .afi = BGP_AF_IPV6_MC,
2512
                .net = NET_IP6,
2513
                .name = "ipv6-mc",
2514
                .encode_nlri = bgp_encode_nlri_ip6,
2515
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2516
                .decode_nlri = bgp_decode_nlri_ip6,
2517
                .encode_next_hop = bgp_encode_next_hop_ip,
2518
                .decode_next_hop = bgp_decode_next_hop_ip,
2519
                .update_next_hop = bgp_update_next_hop_ip,
2520
        },
2521
        {
2522
                .afi = BGP_AF_IPV6_MPLS,
2523
                .net = NET_IP6,
2524
                .mpls = 1,
2525
                .name = "ipv6-mpls",
2526
                .encode_nlri = bgp_encode_nlri_ip6,
2527
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2528
                .decode_nlri = bgp_decode_nlri_ip6,
2529
                .encode_next_hop = bgp_encode_next_hop_ip,
2530
                .decode_next_hop = bgp_decode_next_hop_ip,
2531
                .update_next_hop = bgp_update_next_hop_ip,
2532
        },
2533
        {
2534
                .afi = BGP_AF_VPN4_MPLS,
2535
                .net = NET_VPN4,
2536
                .mpls = 1,
2537
                .name = "vpn4-mpls",
2538
                .encode_nlri = bgp_encode_nlri_vpn4,
2539
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2540
                .decode_nlri = bgp_decode_nlri_vpn4,
2541
                .encode_next_hop = bgp_encode_next_hop_vpn,
2542
                .decode_next_hop = bgp_decode_next_hop_vpn,
2543
                .update_next_hop = bgp_update_next_hop_ip,
2544
        },
2545
        {
2546
                .afi = BGP_AF_VPN6_MPLS,
2547
                .net = NET_VPN6,
2548
                .mpls = 1,
2549
                .name = "vpn6-mpls",
2550
                .encode_nlri = bgp_encode_nlri_vpn6,
2551
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2552
                .decode_nlri = bgp_decode_nlri_vpn6,
2553
                .encode_next_hop = bgp_encode_next_hop_vpn,
2554
                .decode_next_hop = bgp_decode_next_hop_vpn,
2555
                .update_next_hop = bgp_update_next_hop_ip,
2556
        },
2557
        {
2558
                .afi = BGP_AF_VPN4_MC,
2559
                .net = NET_VPN4,
2560
                .name = "vpn4-mc",
2561
                .encode_nlri = bgp_encode_nlri_vpn4,
2562
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2563
                .decode_nlri = bgp_decode_nlri_vpn4,
2564
                .encode_next_hop = bgp_encode_next_hop_vpn,
2565
                .decode_next_hop = bgp_decode_next_hop_vpn,
2566
                .update_next_hop = bgp_update_next_hop_ip,
2567
        },
2568
        {
2569
                .afi = BGP_AF_VPN6_MC,
2570
                .net = NET_VPN6,
2571
                .name = "vpn6-mc",
2572
                .encode_nlri = bgp_encode_nlri_vpn6,
2573
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2574
                .decode_nlri = bgp_decode_nlri_vpn6,
2575
                .encode_next_hop = bgp_encode_next_hop_vpn,
2576
                .decode_next_hop = bgp_decode_next_hop_vpn,
2577
                .update_next_hop = bgp_update_next_hop_ip,
2578
        },
2579
        {
2580
                .afi = BGP_AF_FLOW4,
2581
                .net = NET_FLOW4,
2582
                .no_igp = 1,
2583
                .name = "flow4",
2584
                .encode_nlri = bgp_encode_nlri_flow4,
2585
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2586
                .decode_nlri = bgp_decode_nlri_flow4,
2587
                .encode_next_hop = bgp_encode_next_hop_none,
2588
                .decode_next_hop = bgp_decode_next_hop_none,
2589
                .update_next_hop = bgp_update_next_hop_none,
2590
        },
2591
        {
2592
                .afi = BGP_AF_FLOW6,
2593
                .net = NET_FLOW6,
2594
                .no_igp = 1,
2595
                .name = "flow6",
2596
                .encode_nlri = bgp_encode_nlri_flow6,
2597
                .encode_nlri_mrai = bgp_encode_nlri_ip4_mrai,
2598
                .decode_nlri = bgp_decode_nlri_flow6,
2599
                .encode_next_hop = bgp_encode_next_hop_none,
2600
                .decode_next_hop = bgp_decode_next_hop_none,
2601
                .update_next_hop = bgp_update_next_hop_none,
2602
        },
2603
};
2604

    
2605
const struct bgp_af_desc *
2606
bgp_get_af_desc(u32 afi)
2607
{
2608
    uint i;
2609
    for (i = 0; i < ARRAY_SIZE(bgp_af_table); i++)
2610
        if (bgp_af_table[i].afi == afi)
2611
            return &bgp_af_table[i];
2612

    
2613
    return NULL;
2614
}
2615

    
2616
static inline uint
2617
bgp_encode_nlri(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2618
{
2619
    return s->channel->desc->encode_nlri(s, buck, buf, end - buf);
2620
}
2621

    
2622
static inline uint
2623
bgp_encode_nlri_mrai_destination_based(struct bgp_conn *conn, struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2624
{
2625
    return s->channel->desc->encode_nlri_mrai(conn, s, buck, buf, end - buf);
2626
}
2627

    
2628
static inline uint
2629
bgp_encode_next_hop(struct bgp_write_state *s, eattr *nh, byte *buf)
2630
{
2631
    return s->channel->desc->encode_next_hop(s, nh, buf, 255);
2632
}
2633

    
2634
void
2635
bgp_update_next_hop(struct bgp_export_state *s, eattr *a, ea_list **to)
2636
{
2637
    s->channel->desc->update_next_hop(s, a, to);
2638
}
2639

    
2640
#define MAX_ATTRS_LENGTH (end-buf+BGP_HEADER_LENGTH - 1024)
2641

    
2642
/**
2643
 * For updates with new reachability info
2644
 * @param s
2645
 * @param buck
2646
 * @param buf
2647
 * @param end
2648
 * @return
2649
 */
2650
static byte *
2651
bgp_create_ip_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2652
{
2653
    /*
2654
     *        2 B        Withdrawn Routes Length (zero)
2655
     *        ---        IPv4 Withdrawn Routes NLRI (unused)
2656
     *        2 B        Total Path Attribute Length
2657
     *        var        Path Attributes
2658
     *        var        IPv4 Network Layer Reachability Information
2659
     */
2660

    
2661
    int lr, la;
2662

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

    
2665
    sprintf(buf_as_path, "NONE");
2666
    struct ea_list *eaList = buck->eattrs;
2667
    eattr *e_attr = bgp_find_attr(eaList, BA_AS_PATH);
2668
    if (e_attr != NULL) {
2669
        struct adata *ad = (e_attr->type & EAF_EMBEDDED) ? NULL : e_attr->u.ptr;
2670
        as_path_format(ad, buf_as_path, CLI_MSG_SIZE);
2671
    }
2672

    
2673
    if (la < 0)
2674
    {
2675
        /* Attribute list too long */
2676
        bgp_withdraw_bucket(s->channel, buck);
2677
        return NULL;
2678
    }
2679

    
2680
    put_u16(buf+0, 0);
2681
    put_u16(buf+2, la);
2682

    
2683
    sprintf(dest_ip, "NONE");
2684
    lr = bgp_encode_nlri(s, buck, buf+4+la, end);
2685

    
2686
    return buf+4+la+lr;
2687
}
2688

    
2689
/**
2690
 * For updates with new reachability info
2691
 * @param s
2692
 * @param buck
2693
 * @param buf
2694
 * @param end
2695
 * @return
2696
 */
2697
static byte *
2698
bgp_create_ip_reach_mrai_destination_based(struct bgp_conn *conn, struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2699
{
2700
    /*
2701
     *        2 B        Withdrawn Routes Length (zero)
2702
     *        ---        IPv4 Withdrawn Routes NLRI (unused)
2703
     *        2 B        Total Path Attribute Length
2704
     *        var        Path Attributes
2705
     *        var        IPv4 Network Layer Reachability Information
2706
     */
2707

    
2708
    int lr, la;
2709

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

    
2712
    sprintf(buf_as_path, "NONE");
2713
    struct ea_list *eaList = buck->eattrs;
2714
    eattr *e_attr = bgp_find_attr(eaList, BA_AS_PATH);
2715
    if (e_attr != NULL) {
2716
        struct adata *ad = (e_attr->type & EAF_EMBEDDED) ? NULL : e_attr->u.ptr;
2717
        as_path_format(ad, buf_as_path, CLI_MSG_SIZE);
2718
    }
2719

    
2720
    if (la < 0)
2721
    {
2722
        /* Attribute list too long */
2723
        bgp_withdraw_bucket(s->channel, buck);
2724
        return NULL;
2725
    }
2726

    
2727
    put_u16(buf+0, 0);
2728
    put_u16(buf+2, la);
2729

    
2730
    sprintf(dest_ip, "NONE");
2731
    lr = bgp_encode_nlri_mrai_destination_based(conn, s, buck, buf+4+la, end);
2732

    
2733
    return buf+4+la+lr;
2734
}
2735

    
2736
static byte *
2737
bgp_create_mp_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2738
{
2739
    /*
2740
     *        2 B        IPv4 Withdrawn Routes Length (zero)
2741
     *        ---        IPv4 Withdrawn Routes NLRI (unused)
2742
     *        2 B        Total Path Attribute Length
2743
     *        1 B        MP_REACH_NLRI hdr - Attribute Flags
2744
     *        1 B        MP_REACH_NLRI hdr - Attribute Type Code
2745
     *        2 B        MP_REACH_NLRI hdr - Length of Attribute Data
2746
     *        2 B        MP_REACH_NLRI data - Address Family Identifier
2747
     *        1 B        MP_REACH_NLRI data - Subsequent Address Family Identifier
2748
     *        1 B        MP_REACH_NLRI data - Length of Next Hop Network Address
2749
     *        var        MP_REACH_NLRI data - Network Address of Next Hop
2750
     *        1 B        MP_REACH_NLRI data - Reserved (zero)
2751
     *        var        MP_REACH_NLRI data - Network Layer Reachability Information
2752
     *        var        Rest of Path Attributes
2753
     *        ---        IPv4 Network Layer Reachability Information (unused)
2754
     */
2755

    
2756
    int lh, lr, la;        /* Lengths of next hop, NLRI and attributes */
2757

    
2758
    /* Begin of MP_REACH_NLRI atribute */
2759
    buf[4] = BAF_OPTIONAL | BAF_EXT_LEN;
2760
    buf[5] = BA_MP_REACH_NLRI;
2761
    put_u16(buf+6, 0);                /* Will be fixed later */
2762
    put_af3(buf+8, s->channel->afi);
2763
    byte *pos = buf+11;
2764

    
2765
    /* Encode attributes to temporary buffer */
2766
    byte *abuf = alloca(MAX_ATTRS_LENGTH);
2767
    la = bgp_encode_attrs(s, buck->eattrs, abuf, abuf + MAX_ATTRS_LENGTH);
2768
    if (la < 0)
2769
    {
2770
        /* Attribute list too long */
2771
        bgp_withdraw_bucket(s->channel, buck);
2772
        return NULL;
2773
    }
2774

    
2775
    /* Encode the next hop */
2776
    lh = bgp_encode_next_hop(s, s->mp_next_hop, pos+1);
2777
    *pos = lh;
2778
    pos += 1+lh;
2779

    
2780
net_addr *n;
2781
    /* Reserved field */
2782
    *pos++ = 0;
2783

    
2784
    /* Encode the NLRI */
2785
    lr = bgp_encode_nlri(s, buck, pos, end - la);
2786
    pos += lr;
2787

    
2788
    /* End of MP_REACH_NLRI atribute, update data length */
2789
    put_u16(buf+6, pos-buf-8);
2790

    
2791
    /* Copy remaining attributes */
2792
    memcpy(pos, abuf, la);
2793
    pos += la;
2794

    
2795
    /* Initial UPDATE fields */
2796
    put_u16(buf+0, 0);
2797
    put_u16(buf+2, pos-buf-4);
2798

    
2799
    return pos;
2800
}
2801

    
2802
#undef MAX_ATTRS_LENGTH
2803

    
2804
/**
2805
 * For updates with withdrow reachability information
2806
 * @param s
2807
 * @param buck
2808
 * @param buf
2809
 * @param end
2810
 * @return
2811
 */
2812
static byte *
2813
bgp_create_ip_unreach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2814
{
2815
    /*
2816
     *        2 B        Withdrawn Routes Length
2817
     *        var        IPv4 Withdrawn Routes NLRI
2818
     *        2 B        Total Path Attribute Length (zero)
2819
     *        ---        Path Attributes (unused)
2820
     *        ---        IPv4 Network Layer Reachability Information (unused)
2821
     */
2822
    uint len = bgp_encode_nlri(s, buck, buf+2, end);
2823

    
2824
    put_u16(buf+0, len);
2825
    put_u16(buf+2+len, 0);
2826

    
2827
    return buf+4+len;
2828
}
2829

    
2830
static byte *
2831
bgp_create_mp_unreach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
2832
{
2833
    /*
2834
     *        2 B        Withdrawn Routes Length (zero)
2835
     *        ---        IPv4 Withdrawn Routes NLRI (unused)
2836
     *        2 B        Total Path Attribute Length
2837
     *        1 B        MP_UNREACH_NLRI hdr - Attribute Flags
2838
     *        1 B        MP_UNREACH_NLRI hdr - Attribute Type Code
2839
     *        2 B        MP_UNREACH_NLRI hdr - Length of Attribute Data
2840
     *        2 B        MP_UNREACH_NLRI data - Address Family Identifier
2841
     *        1 B        MP_UNREACH_NLRI data - Subsequent Address Family Identifier
2842
     *        var        MP_UNREACH_NLRI data - Network Layer Reachability Information
2843
     *        ---        IPv4 Network Layer Reachability Information (unused)
2844
     */
2845

    
2846
    uint len = bgp_encode_nlri(s, buck, buf+11, end);
2847

    
2848
    put_u16(buf+0, 0);
2849
    put_u16(buf+2, 7+len);
2850

    
2851
    /* Begin of MP_UNREACH_NLRI atribute */
2852
    buf[4] = BAF_OPTIONAL | BAF_EXT_LEN;
2853
    buf[5] = BA_MP_UNREACH_NLRI;
2854
    put_u16(buf+6, 3+len);
2855
    put_af3(buf+8, s->channel->afi);
2856

    
2857
    return buf+11+len;
2858
}
2859

    
2860
/**
2861
 * Generic function to create an update
2862
 * @param c
2863
 * @param buf
2864
 * @return
2865
 */
2866
static byte *
2867
bgp_create_update(struct bgp_channel *c, byte *buf)
2868
{
2869
    //log(L_INFO "bgp create update");
2870
    struct bgp_proto *p = (void *) c->c.proto;
2871
    struct bgp_bucket *buck;
2872
    byte *end = buf + (bgp_max_packet_length(p->conn) - BGP_HEADER_LENGTH);
2873
    byte *res = NULL;
2874

    
2875
    again: ;
2876

    
2877
    /* Initialize write state */
2878
    struct bgp_write_state s = {
2879
            .proto = p,
2880
            .channel = c,
2881
            .pool = bgp_linpool,
2882
            .as4_session = p->as4_session,
2883
            .add_path = c->add_path_tx,
2884
            .mpls = c->desc->mpls,
2885
    };
2886

    
2887
    /* Try unreachable bucket */
2888
    //If there is information inside this bucket i will send a withdrow
2889
    if ((buck = c->withdraw_bucket) && !EMPTY_LIST(buck->prefixes))
2890
    {
2891
        withdraw_checker = 1;
2892
        res = (c->afi == BGP_AF_IPV4) && !c->ext_next_hop ?
2893
              bgp_create_ip_unreach(&s, buck, buf, end):
2894
              bgp_create_mp_unreach(&s, buck, buf, end);
2895

    
2896
        goto done;
2897
    }
2898

    
2899
    /* Try reachable buckets */
2900
    if (!EMPTY_LIST(c->bucket_queue)) //Il bucket degli indirizzi non è vuoto
2901
    {
2902
        buck = HEAD(c->bucket_queue);
2903

    
2904
        /* Cleanup empty buckets */
2905
        if (EMPTY_LIST(buck->prefixes))
2906
        {
2907
            bgp_free_bucket(c, buck);
2908
            goto again;
2909
        }
2910

    
2911
        /*log(L_INFO "buck prefixes before create ip_reach: ");
2912
        struct bgp_prefix *px;
2913
        WALK_LIST(px, buck->prefixes)
2914
        {
2915
            struct net_addr_ip4 *net = (void *) px->net;
2916
            log(L_INFO
2917
            "Trovata nel bucket rete: %N", &px->net);
2918
        }*/
2919
        res = (c->afi == BGP_AF_IPV4) && !c->ext_next_hop ?
2920
              bgp_create_ip_reach(&s, buck, buf, end):
2921
              bgp_create_mp_reach(&s, buck, buf, end);
2922

    
2923
        if (EMPTY_LIST(buck->prefixes))
2924
            bgp_free_bucket(c, buck);
2925
        else
2926
            bgp_defer_bucket(c, buck);
2927

    
2928
        if (!res)
2929
            goto again;
2930

    
2931
        goto done;
2932
    }
2933

    
2934
    /* No more prefixes to send */
2935
    return NULL;
2936

    
2937
    done:
2938
    BGP_TRACE_RL(&rl_snd_update, D_PACKETS, "Devo inviare un update");
2939
    //TODO spostare queste infor più su, solamente se res non è null
2940
    p->number_of_update_sent += 1;
2941
    total_number_of_update_sent += 1;
2942
    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);
2943
    BGP_TRACE_RL(&rl_snd_update, D_PACKETS, "Sending UPDATE");
2944
    lp_flush(s.pool);
2945

    
2946
    return res;
2947
}
2948

    
2949
/**
2950
 * Generic function to create an update
2951
 * @param c
2952
 * @param buf
2953
 * @return
2954
 */
2955
static byte *
2956
bgp_create_update_mrai_destination_based(struct bgp_conn *conn, struct bgp_channel *c, byte *buf)
2957
{
2958
    struct bgp_proto *p = (void *) c->c.proto;
2959
    struct bgp_bucket *buck;
2960
    byte *end = buf + (bgp_max_packet_length(p->conn) - BGP_HEADER_LENGTH);
2961
    byte *res = NULL;
2962

    
2963
    again: ;
2964
    log(L_INFO "Again");
2965

    
2966
    /* Initialize write state */
2967
    struct bgp_write_state s = {
2968
            .proto = p,
2969
            .channel = c,
2970
            .pool = bgp_linpool,
2971
            .as4_session = p->as4_session,
2972
            .add_path = c->add_path_tx,
2973
            .mpls = c->desc->mpls,
2974
    };
2975

    
2976
    /* Try unreachable bucket */
2977
    //If there is information inside this bucket i will send a withdrow
2978
    if ((buck = c->withdraw_bucket) && !EMPTY_LIST(buck->prefixes))
2979
    {
2980
        withdraw_checker = 1;
2981
        res = (c->afi == BGP_AF_IPV4) && !c->ext_next_hop ?
2982
              bgp_create_ip_unreach(&s, buck, buf, end):
2983
              bgp_create_mp_unreach(&s, buck, buf, end);
2984

    
2985
        log(L_INFO "going in done for unreachable information set");
2986
        goto done;
2987
    }
2988

    
2989
    /* Try reachable buckets */
2990
    log(L_INFO "number of buckets to analize: %d",list_length(&c->bucket_queue));
2991
    if (!EMPTY_LIST(c->bucket_queue)) //Il bucket degli indirizzi non è vuoto
2992
    {
2993
        /* Ciclo sui bucket in quanto alcuni potrebbero essere saltati a causa di indirizzi ritardati da MRAI */
2994
        WALK_LIST(buck, c->bucket_queue)
2995
        {
2996
            /* Cleanup empty buckets */
2997
            if (EMPTY_LIST(buck->prefixes)) {
2998
                bgp_free_bucket(c, buck);
2999
                goto again;
3000
            }
3001

    
3002
            res = (c->afi == BGP_AF_IPV4) && !c->ext_next_hop ?
3003
                  bgp_create_ip_reach_mrai_destination_based(conn, &s, buck, buf, end) :
3004
                  bgp_create_mp_reach(&s, buck, buf, end);
3005

    
3006
            log(L_INFO
3007
            "Res: %d", res);
3008

    
3009
            if (EMPTY_LIST(buck->prefixes))
3010
                bgp_free_bucket(c, buck);
3011

    
3012
            if (!res)
3013
                goto again;
3014

    
3015
            log(L_INFO "prefixAdded: %d", prefixAdded);
3016
            if(prefixAdded > 0) {
3017
                log(L_INFO
3018
                "going in done for reachable information set");
3019
                goto done;
3020
            }
3021
        }
3022
    }
3023

    
3024
    log(L_INFO "Return NULL");
3025
    /* No more prefixes to send */
3026
    return NULL;
3027

    
3028
    done:
3029
    BGP_TRACE_RL(&rl_snd_update, D_PACKETS, "Devo inviare un update");
3030
    p->number_of_update_sent += 1;
3031
    total_number_of_update_sent += 1;
3032
    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);
3033
    BGP_TRACE_RL(&rl_snd_update, D_PACKETS, "Sending UPDATE");
3034
    lp_flush(s.pool);
3035

    
3036
    return res;
3037
}
3038

    
3039
static byte *
3040
bgp_create_ip_end_mark(struct bgp_channel *c UNUSED, byte *buf)
3041
{
3042
    /* Empty update packet */
3043
    put_u32(buf, 0);
3044

    
3045
    return buf+4;
3046
}
3047

    
3048
static byte *
3049
bgp_create_mp_end_mark(struct bgp_channel *c, byte *buf)
3050
{
3051
    put_u16(buf+0, 0);
3052
    put_u16(buf+2, 6);                /* length 4--9 */
3053

    
3054
    /* Empty MP_UNREACH_NLRI atribute */
3055
    buf[4] = BAF_OPTIONAL;
3056
    buf[5] = BA_MP_UNREACH_NLRI;
3057
    buf[6] = 3;                        /* Length 7--9 */
3058
    put_af3(buf+7, c->afi);
3059

    
3060
    return buf+10;
3061
}
3062

    
3063
static byte *
3064
bgp_create_end_mark(struct bgp_channel *c, byte *buf)
3065
{
3066
    struct bgp_proto *p = (void *) c->c.proto;
3067

    
3068
    BGP_TRACE(D_PACKETS, "Sending END-OF-RIB");
3069

    
3070
    return (c->afi == BGP_AF_IPV4) ?
3071
           bgp_create_ip_end_mark(c, buf):
3072
           bgp_create_mp_end_mark(c, buf);
3073
}
3074

    
3075
static inline void
3076
bgp_rx_end_mark(struct bgp_parse_state *s, u32 afi)
3077
{
3078
    struct bgp_proto *p = s->proto;
3079
    struct bgp_channel *c = bgp_get_channel(p, afi);
3080

    
3081
    BGP_TRACE(D_PACKETS, "Got END-OF-RIB");
3082

    
3083
    if (!c)
3084
        DISCARD(BAD_AFI, BGP_AFI(afi), BGP_SAFI(afi));
3085

    
3086
    if (c->load_state == BFS_LOADING)
3087
        c->load_state = BFS_NONE;
3088

    
3089
    if (p->p.gr_recovery)
3090
        channel_graceful_restart_unlock(&c->c);
3091

    
3092
    if (c->gr_active)
3093
        bgp_graceful_restart_done(c);
3094
}
3095

    
3096
/**
3097
 * Generic NLRI decode, to invoke the specific NLRI decoder
3098
 * @param s
3099
 * @param afi
3100
 * @param nlri
3101
 * @param len
3102
 * @param ea
3103
 * @param nh
3104
 * @param nh_len
3105
 */
3106
static inline void
3107
bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_list *ea, byte *nh, uint nh_len)
3108
{
3109
    struct bgp_channel *c = bgp_get_channel(s->proto, afi);
3110
    rta *a = NULL;
3111

    
3112
    if (!c)
3113
        DISCARD(BAD_AFI, BGP_AFI(afi), BGP_SAFI(afi));
3114

    
3115
    s->channel = c;
3116
    s->add_path = c->add_path_rx;
3117
    s->mpls = c->desc->mpls;
3118

    
3119
    s->last_id = 0;
3120
    s->last_src = s->proto->p.main_source;
3121

    
3122
    //TODO not sure this is the right thing to do
3123
    if(nh_len == 0){
3124
        //log(L_INFO "Trovato withdraw");
3125
        withdraw_checker = 1;
3126
    }
3127

    
3128
    /*
3129
     * IPv4 BGP and MP-BGP may be used together in one update, therefore we do not
3130
     * add BA_NEXT_HOP in bgp_decode_attrs(), but we add it here independently for
3131
     * IPv4 BGP and MP-BGP. We undo the attribute (and possibly others attached by
3132
     * decode_next_hop hooks) by restoring a->eattrs afterwards.
3133
     */
3134

    
3135
    if (ea)
3136
    {
3137
        a = allocz(RTA_MAX_SIZE);
3138

    
3139
        a->source = RTS_BGP;
3140
        a->scope = SCOPE_UNIVERSE;
3141
        a->from = s->proto->cf->remote_ip;
3142
        a->eattrs = ea;
3143

    
3144
        c->desc->decode_next_hop(s, nh, nh_len, a);
3145
        //eattr *e = bgp_find_attr(ea, BA_NEXT_HOP);
3146
        /* Handle withdraw during next hop decoding */
3147
        if (s->err_withdraw)
3148
            a = NULL;
3149
    }
3150

    
3151
    c->desc->decode_nlri(s, nlri, len, a);
3152
    rta_free(s->cached_rta);
3153
    s->cached_rta = NULL;
3154
}
3155

    
3156
static inline struct bgp_channel *
3157
bgp_get_channel_to_send(struct bgp_proto *p, struct bgp_conn *conn)
3158
{
3159
    uint i = conn->last_channel;
3160

    
3161
    /* Try the last channel, but at most several times */
3162
    if ((conn->channels_to_send & (1 << i)) &&
3163
        (conn->last_channel_count < 16))
3164
        goto found;
3165

    
3166
    /* Find channel with non-zero channels_to_send */
3167
    do
3168
    {
3169
        i++;
3170
        if (i >= p->channel_count)
3171
            i = 0;
3172
    }
3173
    while (! (conn->channels_to_send & (1 << i)));
3174

    
3175
    /* Use that channel */
3176
    conn->last_channel = i;
3177
    conn->last_channel_count = 0;
3178

    
3179
    found:
3180
    conn->last_channel_count++;
3181
    return p->channel_map[i];
3182
}
3183

    
3184
static void
3185
bgp_rx_update(struct bgp_conn *conn, byte *pkt, uint len)
3186
{
3187
    NHChanged = 0;
3188

    
3189
    char output[50];
3190
    float tmpLoad = loadComplessivo;
3191
    snprintf(output, 50, "%f", loadComplessivo);
3192

    
3193
    withdraw_checker = 0;
3194
    struct bgp_proto *p = conn->bgp;
3195
    snprintf(ASLocale, 12, "%d", p->public_as);
3196

    
3197
    log(L_INFO "Load complessivo pre update: %s", output);
3198

    
3199
    ea_list *ea = NULL;
3200

    
3201
    rilevatoLoop = 0;
3202
    ASRicezione = p->remote_as;
3203
    BGP_TRACE_RL(&rl_rcv_update, D_PACKETS, "Got UPDATE");
3204

    
3205
    /* Workaround for some BGP implementations that skip initial KEEPALIVE */
3206
    if (conn->state == BS_OPENCONFIRM)
3207
        bgp_conn_enter_established_state(conn);
3208

    
3209
    if (conn->state != BS_ESTABLISHED)
3210
    { bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0); return; }
3211

    
3212
    bgp_start_timer(conn->hold_timer, conn->hold_time);
3213

    
3214
    /* Initialize parse state */
3215
    struct bgp_parse_state s = {
3216
            .proto = p,
3217
            .pool = bgp_linpool,
3218
            .as4_session = p->as4_session,
3219
    };
3220

    
3221
    /* Parse error handler */
3222
    if (setjmp(s.err_jmpbuf))
3223
    {
3224
        bgp_error(conn, 3, s.err_subcode, NULL, 0);
3225
        goto done;
3226
    }
3227

    
3228
    /* Check minimal length */
3229
    if (len < 23)
3230
    { bgp_error(conn, 1, 2, pkt+16, 2); return; }
3231

    
3232
    /* Skip fixed header */
3233
    uint pos = 19;
3234

    
3235
    /*
3236
     *        UPDATE message format
3237
     *
3238
     *        2 B        IPv4 Withdrawn Routes Length
3239
     *        var        IPv4 Withdrawn Routes NLRI
3240
     *        2 B        Total Path Attribute Length
3241
     *        var        Path Attributes
3242
     *        var        IPv4 Reachable Routes NLRI
3243
     */
3244

    
3245
    s.ip_unreach_len = get_u16(pkt + pos);
3246
    s.ip_unreach_nlri = pkt + pos + 2;
3247
    pos += 2 + s.ip_unreach_len;
3248

    
3249
    if (pos + 2 > len)
3250
        bgp_parse_error(&s, 1);
3251

    
3252
    s.attr_len = get_u16(pkt + pos);
3253
    s.attrs = pkt + pos + 2;
3254
    pos += 2 + s.attr_len;
3255

    
3256
    if (pos > len)
3257
        bgp_parse_error(&s, 1);
3258

    
3259
    s.ip_reach_len = len - pos;
3260
    s.ip_reach_nlri = pkt + pos;
3261

    
3262
    //TODO remove
3263
    sonoIlNH = 0;
3264
    numeroNHarrivati = 0.0;
3265
    loadOutRilevato = 0.0;
3266

    
3267
    if (s.attr_len)
3268
        ea = bgp_decode_attrs(&s, s.attrs, s.attr_len);
3269
    else
3270
        ea = NULL;
3271

    
3272
    /* Check for End-of-RIB marker */
3273
    if (!s.attr_len && !s.ip_unreach_len && !s.ip_reach_len)
3274
    { bgp_rx_end_mark(&s, BGP_AF_IPV4); goto done; }
3275

    
3276
    /* Check for MP End-of-RIB marker */
3277
    if ((s.attr_len < 8) && !s.ip_unreach_len && !s.ip_reach_len &&
3278
        !s.mp_reach_len && !s.mp_unreach_len && s.mp_unreach_af)
3279
    { bgp_rx_end_mark(&s, s.mp_unreach_af); goto done; }
3280

    
3281
    //char asCKey[12];
3282
    //sprintf(nhCKey, "%d", nhKey);
3283
    //sprintf(asCKey, "%d", ASRicezione);
3284

    
3285
    eattr *e = bgp_find_attr(ea, BA_AS_PATH);
3286
    if (e != NULL) {
3287
        struct adata *ad = (e->type & EAF_EMBEDDED) ? NULL : e->u.ptr;
3288
        as_path_format(ad, buf_as_path, CLI_MSG_SIZE);
3289

    
3290
        //log(L_FATAL
3291
        //"{type: UPDATE_RX, dest: %s, from: %s, nh: %s, as_path: %s}",ipAddrRec, asCKey, nhCKey, buf);
3292
    }
3293

    
3294
    if (s.ip_unreach_len)
3295
        bgp_decode_nlri(&s, BGP_AF_IPV4, s.ip_unreach_nlri, s.ip_unreach_len, NULL, NULL, 0);
3296

    
3297
    if (s.mp_unreach_len)
3298
        bgp_decode_nlri(&s, s.mp_unreach_af, s.mp_unreach_nlri, s.mp_unreach_len, NULL, NULL, 0);
3299

    
3300
    if (s.ip_reach_len)
3301
        bgp_decode_nlri(&s, BGP_AF_IPV4, s.ip_reach_nlri, s.ip_reach_len,
3302
                        ea, s.ip_next_hop_data, s.ip_next_hop_len);
3303

    
3304
    if (s.mp_reach_len)
3305
        bgp_decode_nlri(&s, s.mp_reach_af, s.mp_reach_nlri, s.mp_reach_len,
3306
                        ea, s.mp_next_hop_data, s.mp_next_hop_len);
3307

    
3308
    done:
3309
    rta_free(s.cached_rta);
3310
    lp_flush(s.pool);
3311

    
3312
    //TODO I think the memory problem is here
3313
    if (tmpLoad != loadComplessivo){
3314
        //log(L_FATAL "LOAD COMPLESSIVO VARIATO");
3315

    
3316
        RTable *objFound = map_get(RTmap, cKey);
3317
        if (objFound == NULL){
3318
            log(L_INFO "objfound è null");
3319
        }
3320
        else if (objFound->P == NULL){
3321
            log(L_INFO "objFound->P è null");
3322
        }
3323
        else if (objFound->C == NULL){
3324
            log(L_INFO "objFound->C è null");
3325
        }
3326
        else if (objFound->n == NULL){
3327
            log(L_INFO "objFound->n è null");
3328
        }
3329
        else if (objFound->rtElem == NULL){
3330
            log(L_INFO "objFound->rtElem è null");
3331
        }
3332
        else {
3333
            int tmp = 0;
3334
            int i = 0;
3335
            //bgp_show_proto_info_mine((void *)objFound->P);
3336
            map_iter_t iter3 = map_iter(objFound->NH);
3337
            const char *key3;
3338
            while ((key3 = map_next(objFound->NH, &iter3))) {
3339
                i++;
3340
                int *NHmap = map_get(objFound->NH, key3);
3341
                if (*NHmap == ASRicezione) {
3342
                    tmp = 1;
3343
                }
3344
            }
3345
            if (tmp == 0 && i > 0) {
3346
                //Force RT_notify
3347
                objFound->P->rt_notify(objFound->P, objFound->C, objFound->n, objFound->rtElem, NULL, objFound->rtElem->attrs->eattrs);
3348
                /*ea = objFound->rtElem->attrs->eattrs;
3349
                struct bgp_proto *pr = (void *)objFound->P;
3350
                struct bgp_channel *ch = (void *)objFound->C;
3351
                rte *new = objFound->rtElem;
3352
                net *n = objFound->n;
3353
                struct bgp_bucket *buck;
3354
                struct bgp_prefix *px;
3355
                u32 path;
3356
                ea = bgp_update_attrs(pr, ch, new, ea, bgp_linpool2);
3357
                if(ea) {
3358
                    buck = bgp_get_bucket(ch, ea);
3359
                    path = new->attrs->src->global_id;
3360
                    lp_flush(bgp_linpool2);
3361
                    px = bgp_get_prefix(ch, n->n.addr, ch->add_path_tx ? path : 0);
3362
                    add_tail(&buck->prefixes, &px->buck_node);
3363
                    bgp_schedule_packet(pr->conn, ch, PKT_UPDATE);
3364
                }*/
3365
            }
3366
        }
3367
    } else {
3368
        //log(L_FATAL "Load complessivo invariato");
3369
    }
3370

    
3371
    if (NHChanged == 1){
3372
        log(L_FATAL "NH VARIATO");
3373

    
3374
        RTable objFound = tmpElem;
3375
        if (objFound.P == NULL){
3376
            log(L_INFO "objFound->P è null");
3377
        }
3378
        else if (objFound.C == NULL){
3379
            log(L_INFO "objFound->C è null");
3380
        }
3381
        else if (objFound.n == NULL){
3382
            log(L_INFO "objFound->n è null");
3383
        }
3384
        else if (objFound.rtElem == NULL){
3385
            log(L_INFO "objFound->rtElem è null");
3386
        }
3387
        else {
3388
            /*int tmp = 0;
3389
            int i = 0;
3390
            //bgp_show_proto_info_mine((void *)objFound->P);
3391
            map_iter_t iter3 = map_iter(&objFound->NH);
3392
            const char *key3;
3393
            while ((key3 = map_next(&objFound->NH, &iter3))) {
3394
                i++;
3395
                int *NHmap = map_get(&objFound->NH, key3);
3396
                if (*NHmap == ASRicezione) {
3397
                    tmp = 1;
3398
                }
3399
            }
3400
            if (tmp == 0 && i > 0) {
3401
                //Force RT_notify*/
3402
                objFound.P->rt_notify(objFound.P, objFound.C, objFound.n, objFound.rtElem, NULL, objFound.rtElem->attrs->eattrs);
3403
            //}
3404
        }
3405
    } else {
3406
        //log(L_FATAL "NH invariato");
3407
    }
3408

    
3409
    return;
3410
}
3411

    
3412

    
3413
/*
3414
 *        ROUTE-REFRESH
3415
 */
3416

    
3417
static inline byte *
3418
bgp_create_route_refresh(struct bgp_channel *c, byte *buf)
3419
{
3420
    struct bgp_proto *p = (void *) c->c.proto;
3421

    
3422
    BGP_TRACE(D_PACKETS, "Sending ROUTE-REFRESH");
3423

    
3424
    /* Original route refresh request, RFC 2918 */
3425
    put_af4(buf, c->afi);
3426
    buf[2] = BGP_RR_REQUEST;
3427

    
3428
    return buf+4;
3429
}
3430

    
3431
static inline byte *
3432
bgp_create_begin_refresh(struct bgp_channel *c, byte *buf)
3433
{
3434
    struct bgp_proto *p = (void *) c->c.proto;
3435

    
3436
    BGP_TRACE(D_PACKETS, "Sending BEGIN-OF-RR");
3437

    
3438
    /* Demarcation of beginning of route refresh (BoRR), RFC 7313 */
3439
    put_af4(buf, c->afi);
3440
    buf[2] = BGP_RR_BEGIN;
3441

    
3442
    return buf+4;
3443
}
3444

    
3445
static inline byte *
3446
bgp_create_end_refresh(struct bgp_channel *c, byte *buf)
3447
{
3448
    struct bgp_proto *p = (void *) c->c.proto;
3449

    
3450
    BGP_TRACE(D_PACKETS, "Sending END-OF-RR");
3451

    
3452
    /* Demarcation of ending of route refresh (EoRR), RFC 7313 */
3453
    put_af4(buf, c->afi);
3454
    buf[2] = BGP_RR_END;
3455

    
3456
    return buf+4;
3457
}
3458

    
3459
static void
3460
bgp_rx_route_refresh(struct bgp_conn *conn, byte *pkt, uint len)
3461
{
3462
    struct bgp_proto *p = conn->bgp;
3463

    
3464
    if (conn->state != BS_ESTABLISHED)
3465
    { bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0); return; }
3466

    
3467
    if (!conn->local_caps->route_refresh)
3468
    { bgp_error(conn, 1, 3, pkt+18, 1); return; }
3469

    
3470
    if (len < (BGP_HEADER_LENGTH + 4))
3471
    { bgp_error(conn, 1, 2, pkt+16, 2); return; }
3472

    
3473
    if (len > (BGP_HEADER_LENGTH + 4))
3474
    { bgp_error(conn, 7, 1, pkt, MIN(len, 2048)); return; }
3475

    
3476
    struct bgp_channel *c = bgp_get_channel(p, get_af4(pkt+19));
3477
    if (!c)
3478
    {
3479
        log(L_WARN "%s: Got ROUTE-REFRESH subtype %u for AF %u.%u, ignoring",
3480
                p->p.name, pkt[21], get_u16(pkt+19), pkt[22]);
3481
        return;
3482
    }
3483

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

    
3487
    switch (subtype)
3488
    {
3489
        case BGP_RR_REQUEST:
3490
            BGP_TRACE(D_PACKETS, "Got ROUTE-REFRESH");
3491
            channel_request_feeding(&c->c);
3492
            break;
3493

    
3494
        case BGP_RR_BEGIN:
3495
            BGP_TRACE(D_PACKETS, "Got BEGIN-OF-RR");
3496
            bgp_refresh_begin(c);
3497
            break;
3498

    
3499
        case BGP_RR_END:
3500
            BGP_TRACE(D_PACKETS, "Got END-OF-RR");
3501
            bgp_refresh_end(c);
3502
            break;
3503

    
3504
        default:
3505
            log(L_WARN "%s: Got ROUTE-REFRESH message with unknown subtype %u, ignoring",
3506
            p->p.name, subtype);
3507
            break;
3508
    }
3509
}
3510

    
3511
static inline int
3512
bgp_send(struct bgp_conn *conn, uint type, uint len)
3513
{
3514
    sock *sk = conn->sk;
3515
    byte *buf = sk->tbuf;
3516

    
3517
    memset(buf, 0xff, 16);                /* Marker */
3518
    put_u16(buf+16, len);
3519
    buf[18] = type;
3520

    
3521
    return sk_send(sk, len);
3522
}
3523

    
3524
void
3525
bgp_study_delayed_buck(struct bgp_bucket *buck){
3526
    log(L_INFO "bgp_study_delayed_buck");
3527
    if(buck) {
3528
        struct bgp_prefix *px;
3529
        log(L_INFO "Prefix list len: %d", list_length(&buck->prefixes));
3530
        WALK_LIST(px,buck->prefixes){
3531
            px->net->type = 1;
3532
            char time[TM_DATETIME_BUFFER_SIZE];
3533
            tm_format_time(time, &TM_ISO_SHORT_MS, px->sharing_time);
3534
            char share_time[TM_DATETIME_BUFFER_SIZE];
3535
            tm_format_time(share_time, &TM_ISO_SHORT_MS, px->end_mrai);
3536
            log(L_INFO
3537
            "Trovata nel bucket rete: %N con timer: %s verrà condivso dopo: %s", &px->net, time, share_time);
3538
        }
3539
        log(L_INFO
3540
        "no more delayed prefixes");
3541
    }
3542
    else
3543
    {
3544
        log(L_INFO "bucket not initialized");
3545
    }
3546
}
3547

    
3548
/**
3549
 * bgp_fire_tx - transmit packets
3550
 * @conn: connection
3551
 *
3552
 * Whenever the transmit buffers of the underlying TCP connection
3553
 * are free and we have any packets queued for sending, the socket functions
3554
 * call bgp_fire_tx() which takes care of selecting the highest priority packet
3555
 * queued (Notification > Keepalive > Open > Update), assembling its header
3556
 * and body and sending it to the connection.
3557
 */
3558
int
3559
bgp_fire_tx(struct bgp_conn *conn)
3560
{
3561
    struct bgp_proto *p = conn->bgp;
3562
    struct bgp_channel *c;
3563
    byte *buf, *pkt, *end;
3564
    uint s;
3565

    
3566
    if (!conn->sk)
3567
        return 0;
3568

    
3569
    buf = conn->sk->tbuf;
3570
    pkt = buf + BGP_HEADER_LENGTH;
3571
    s = conn->packets_to_send;
3572

    
3573
    if (s & (1 << PKT_SCHEDULE_CLOSE))
3574
    {
3575
        /* We can finally close connection and enter idle state */
3576
        bgp_conn_enter_idle_state(conn);
3577
        return 0;
3578
    }
3579
    if (s & (1 << PKT_NOTIFICATION))
3580
    {
3581
        conn->packets_to_send = 1 << PKT_SCHEDULE_CLOSE;
3582
        end = bgp_create_notification(conn, pkt);
3583
        return bgp_send(conn, PKT_NOTIFICATION, end - buf);
3584
    }
3585
    else if (s & (1 << PKT_KEEPALIVE))
3586
    {
3587
        conn->packets_to_send &= ~(1 << PKT_KEEPALIVE);
3588
        BGP_TRACE(D_PACKETS, "Sending KEEPALIVE");
3589
        bgp_start_timer(conn->keepalive_timer, conn->keepalive_time);
3590
        return bgp_send(conn, PKT_KEEPALIVE, BGP_HEADER_LENGTH);
3591
    }
3592
    else if (s & (1 << PKT_OPEN))
3593
    {
3594
        conn->packets_to_send &= ~(1 << PKT_OPEN);
3595
        end = bgp_create_open(conn, pkt);
3596
        return bgp_send(conn, PKT_OPEN, end - buf);
3597
    }
3598
    else while (conn->channels_to_send &&
3599
                !((s & (1 << PKT_UPDATE)) && tm_active(conn->conn_mrai_timer) && conn->bgp->cf->mrai_type == 0))
3600
        {
3601
            c = bgp_get_channel_to_send(p, conn);
3602
            s = c->packets_to_send;
3603

    
3604
            if (s & (1 << PKT_ROUTE_REFRESH))
3605
            {
3606
                c->packets_to_send &= ~(1 << PKT_ROUTE_REFRESH);
3607
                end = bgp_create_route_refresh(c, pkt);
3608
                return bgp_send(conn, PKT_ROUTE_REFRESH, end - buf);
3609
            }
3610
            else if (s & (1 << PKT_BEGIN_REFRESH))
3611
            {
3612
                /* BoRR is a subtype of RR, but uses separate bit in packets_to_send */
3613
                c->packets_to_send &= ~(1 << PKT_BEGIN_REFRESH);
3614
                end = bgp_create_begin_refresh(c, pkt);
3615
                return bgp_send(conn, PKT_ROUTE_REFRESH, end - buf);
3616
            }
3617
            else if (s & (1 << PKT_UPDATE))
3618
            {
3619
                BGP_TRACE(D_PACKETS, "Ho un pkt di UPDATE da inviare");
3620
                log(L_INFO "Ho un pkt di UPDATE da inviare");
3621
                /* MRAI timer peer-based */
3622
                if(conn->bgp->cf->mrai_type == 0) {
3623
                    if (!tm_active(conn->conn_mrai_timer)) {
3624
                        BGP_TRACE(D_PACKETS, "Il timer MRAI non è attivo");
3625
                        withdraw_checker = 0;
3626
                        end = bgp_create_update(c, pkt);
3627
                        BGP_TRACE(D_PACKETS, "Pacchetto creato");
3628

    
3629
                        if (end) {
3630
                            /* Enable the timer only if the mrai timer is different than 0 */
3631
                            if(withdraw_checker == 0) {
3632
                                log(L_INFO
3633
                                "mrai type: %d", conn->bgp->cf->mrai_type);
3634
                                if (conn->bgp->cf->mrai_time != 0) {
3635
                                    BGP_TRACE(D_PACKETS,
3636
                                              "CONFERMATO PKT UPDATE, avvio il timer considerando un delay di %d ms",
3637
                                              conn->bgp->cf->mrai_time);
3638
                                    bgp_start_ms_timer(conn->conn_mrai_timer, conn->bgp->cf->mrai_time, conn->bgp->cf->mrai_jitter);
3639
                                }
3640
                                log(L_FATAL
3641
                                "{type: UPDATE_TX, dest: %s, to: %d, as_path: %s}", dest_ip, p->remote_as, buf_as_path);
3642
                            }
3643
                            return bgp_send(conn, PKT_UPDATE, end - buf);
3644
                        }
3645

    
3646
                        /* No update to send, perhaps we need to send End-of-RIB or EoRR */
3647
                        c->packets_to_send = 0;
3648
                        conn->channels_to_send &= ~(1 << c->index);
3649

    
3650
                        if (c->feed_state == BFS_LOADED) {
3651
                            c->feed_state = BFS_NONE;
3652
                            end = bgp_create_end_mark(c, pkt);
3653
                            return bgp_send(conn, PKT_UPDATE, end - buf);
3654
                        } else if (c->feed_state == BFS_REFRESHED) {
3655
                            c->feed_state = BFS_NONE;
3656
                            end = bgp_create_end_refresh(c, pkt);
3657
                            return bgp_send(conn, PKT_ROUTE_REFRESH, end - buf);
3658
                        }
3659

    
3660
                        c->packets_to_send = 0;
3661
                        conn->channels_to_send &= ~(1 << c->index);
3662
                    } else {
3663
                        BGP_TRACE(D_PACKETS, "Il timer MRAI è attivo");
3664
                    }
3665
                }
3666
                else { /* MRAI timer destination-based */
3667
                    BGP_TRACE(D_PACKETS, "Il timer MRAI non è attivo");
3668
                    prefixAdded = 0;
3669
                    withdraw_checker = 0;
3670
                    /* Utilizzo di una funzione specifica per la creazione del pacchetto */
3671
                    end = bgp_create_update_mrai_destination_based(conn, c, pkt);
3672
                    BGP_TRACE(D_PACKETS, "Pacchetto creato");
3673
                    bgp_study_delayed_buck(delayed_bucket);
3674

    
3675
                    if(prefixAdded == 0 && withdraw_checker == 0){
3676
                        log(L_INFO "Nessuna rotta aggiunta al pacchetto");
3677
                        return 0;
3678
                    }
3679

    
3680
                    if (end) {
3681
                        if(withdraw_checker == 0) {
3682
                            log(L_INFO
3683
                            "mrai type: %d", conn->bgp->cf->mrai_type);
3684
                            log(L_FATAL
3685
                            "{type: UPDATE_TX, dest: %s, to: %d, as_path: %s}", dest_ip, p->remote_as, buf_as_path);
3686
                        }
3687
                        return bgp_send(conn, PKT_UPDATE, end - buf);
3688
                    }
3689

    
3690
                    /* No update to send, perhaps we need to send End-of-RIB or EoRR */
3691
                    c->packets_to_send = 0;
3692
                    conn->channels_to_send &= ~(1 << c->index);
3693

    
3694
                    if (c->feed_state == BFS_LOADED) {
3695
                        c->feed_state = BFS_NONE;
3696
                        end = bgp_create_end_mark(c, pkt);
3697
                        return bgp_send(conn, PKT_UPDATE, end - buf);
3698
                    } else if (c->feed_state == BFS_REFRESHED) {
3699
                        c->feed_state = BFS_NONE;
3700
                        end = bgp_create_end_refresh(c, pkt);
3701
                        return bgp_send(conn, PKT_ROUTE_REFRESH, end - buf);
3702
                    }
3703

    
3704
                    //TODO this code is repeated twice
3705
                    c->packets_to_send = 0;
3706
                    conn->channels_to_send &= ~(1 << c->index);
3707
                }
3708
            }
3709
            else if (s) {
3710
                bug("Channel packets_to_send: %x", s);
3711

    
3712
                c->packets_to_send = 0;
3713
                conn->channels_to_send &= ~(1 << c->index);
3714
            }
3715
        }
3716

    
3717
    return 0;
3718
}
3719

    
3720
/**
3721
 * bgp_schedule_packet - schedule a packet for transmission
3722
 * @conn: connection
3723
 * @c: channel
3724
 * @type: packet type
3725
 *
3726
 * Schedule a packet of type @type to be sent as soon as possible.
3727
 */
3728
void
3729
bgp_schedule_packet(struct bgp_conn *conn, struct bgp_channel *c, int type)
3730
{
3731
    log(L_INFO "bgp_schedule_packet");
3732
    ASSERT(conn->sk);
3733

    
3734
    DBG("BGP: Scheduling packet type %d\n", type);
3735
    log(L_INFO "BGP: Scheduling packet type %d", type);
3736
    if (c)
3737
    {
3738
        // log(L_INFO "c not null");
3739
        if (! conn->channels_to_send)
3740
        {
3741
            // log(L_INFO "! conn->channels_to_send");
3742
            conn->last_channel = c->index;
3743
            conn->last_channel_count = 0;
3744
        }
3745
        // log(L_INFO "idk 1");
3746
        c->packets_to_send |= 1 << type;
3747
        conn->channels_to_send |= 1 << c->index;
3748
    }
3749
    else {
3750
        conn->packets_to_send |= 1 << type;
3751
        // log(L_INFO "idk 2");
3752
    }
3753

    
3754
    if ((conn->sk->tpos == conn->sk->tbuf) && !ev_active(conn->tx_ev)) {
3755
        /*if(type == PKT_UPDATE) {
3756
            log(L_FATAL
3757
            "UPDATE schedulato!");
3758
        }*/
3759
        ev_schedule(conn->tx_ev);
3760
    }
3761
}
3762

    
3763
void
3764
bgp_kick_tx(void *vconn)
3765
{
3766
    struct bgp_conn *conn = vconn;
3767
    DBG("BGP: kicking TX\n");
3768

    
3769
    while (bgp_fire_tx(conn) > 0)
3770
        ;
3771
}
3772

    
3773
void
3774
bgp_tx(sock *sk)
3775
{
3776
    struct bgp_conn *conn = sk->data;
3777
    DBG("BGP: TX hook\n");
3778
    while (bgp_fire_tx(conn) > 0)
3779
        ;
3780
}
3781

    
3782

    
3783
static struct {
3784
    byte major, minor;
3785
    byte *msg;
3786
} bgp_msg_table[] = {
3787
        { 1, 0, "Invalid message header" },
3788
        { 1, 1, "Connection not synchronized" },
3789
        { 1, 2, "Bad message length" },
3790
        { 1, 3, "Bad message type" },
3791
        { 2, 0, "Invalid OPEN message" },
3792
        { 2, 1, "Unsupported version number" },
3793
        { 2, 2, "Bad peer AS" },
3794
        { 2, 3, "Bad BGP identifier" },
3795
        { 2, 4, "Unsupported optional parameter" },
3796
        { 2, 5, "Authentication failure" },
3797
        { 2, 6, "Unacceptable hold time" },
3798
        { 2, 7, "Required capability missing" }, /* [RFC5492] */
3799
        { 2, 8, "No supported AFI/SAFI" }, /* This error msg is nonstandard */
3800
        { 3, 0, "Invalid UPDATE message" },
3801
        { 3, 1, "Malformed attribute list" },
3802
        { 3, 2, "Unrecognized well-known attribute" },
3803
        { 3, 3, "Missing mandatory attribute" },
3804
        { 3, 4, "Invalid attribute flags" },
3805
        { 3, 5, "Invalid attribute length" },
3806
        { 3, 6, "Invalid ORIGIN attribute" },
3807
        { 3, 7, "AS routing loop" },                /* Deprecated */
3808
        { 3, 8, "Invalid NEXT_HOP attribute" },
3809
        { 3, 9, "Optional attribute error" },
3810
        { 3, 10, "Invalid network field" },
3811
        { 3, 11, "Malformed AS_PATH" },
3812
        { 4, 0, "Hold timer expired" },
3813
        { 5, 0, "Finite state machine error" }, /* Subcodes are according to [RFC6608] */
3814
        { 5, 1, "Unexpected message in OpenSent state" },
3815
        { 5, 2, "Unexpected message in OpenConfirm state" },
3816
        { 5, 3, "Unexpected message in Established state" },
3817
        { 6, 0, "Cease" }, /* Subcodes are according to [RFC4486] */
3818
        { 6, 1, "Maximum number of prefixes reached" },
3819
        { 6, 2, "Administrative shutdown" },
3820
        { 6, 3, "Peer de-configured" },
3821
        { 6, 4, "Administrative reset" },
3822
        { 6, 5, "Connection rejected" },
3823
        { 6, 6, "Other configuration change" },
3824
        { 6, 7, "Connection collision resolution" },
3825
        { 6, 8, "Out of Resources" },
3826
        { 7, 0, "Invalid ROUTE-REFRESH message" }, /* [RFC7313] */
3827
        { 7, 1, "Invalid ROUTE-REFRESH message length" } /* [RFC7313] */
3828
};
3829

    
3830
/**
3831
 * bgp_error_dsc - return BGP error description
3832
 * @code: BGP error code
3833
 * @subcode: BGP error subcode
3834
 *
3835
 * bgp_error_dsc() returns error description for BGP errors
3836
 * which might be static string or given temporary buffer.
3837
 */
3838
const char *
3839
bgp_error_dsc(uint code, uint subcode)
3840
{
3841
    static char buff[32];
3842
    uint i;
3843

    
3844
    for (i=0; i < ARRAY_SIZE(bgp_msg_table); i++)
3845
        if (bgp_msg_table[i].major == code && bgp_msg_table[i].minor == subcode)
3846
            return bgp_msg_table[i].msg;
3847

    
3848
    bsprintf(buff, "Unknown error %u.%u", code, subcode);
3849
    return buff;
3850
}
3851

    
3852
/* RFC 8203 - shutdown communication message */
3853
static int
3854
bgp_handle_message(struct bgp_proto *p, byte *data, uint len, byte **bp)
3855
{
3856
    byte *msg = data + 1;
3857
    uint msg_len = data[0];
3858
    uint i;
3859

    
3860
    /* Handle zero length message */
3861
    if (msg_len == 0)
3862
        return 1;
3863

    
3864
    /* Handle proper message */
3865
    if ((msg_len > 128) && (msg_len + 1 > len))
3866
        return 0;
3867

    
3868
    /* Some elementary cleanup */
3869
    for (i = 0; i < msg_len; i++)
3870
        if (msg[i] < ' ')
3871
            msg[i] = ' ';
3872

    
3873
    proto_set_message(&p->p, msg, msg_len);
3874
    *bp += bsprintf(*bp, ": \"%s\"", p->p.message);
3875
    return 1;
3876
}
3877

    
3878
void
3879
bgp_log_error(struct bgp_proto *p, u8 class, char *msg, uint code, uint subcode, byte *data, uint len)
3880
{
3881
    byte argbuf[256], *t = argbuf;
3882
    uint i;
3883

    
3884
    /* Don't report Cease messages generated by myself */
3885
    if (code == 6 && class == BE_BGP_TX)
3886
    return;
3887

    
3888
    /* Reset shutdown message */
3889
    if ((code == 6) && ((subcode == 2) || (subcode == 4)))
3890
        proto_set_message(&p->p, NULL, 0);
3891

    
3892
    if (len)
3893
    {
3894
        /* Bad peer AS - we would like to print the AS */
3895
        if ((code == 2) && (subcode == 2) && ((len == 2) || (len == 4)))
3896
        {
3897
            t += bsprintf(t, ": %u", (len == 2) ? get_u16(data) : get_u32(data));
3898
            goto done;
3899
        }
3900

    
3901
        /* RFC 8203 - shutdown communication */
3902
        if (((code == 6) && ((subcode == 2) || (subcode == 4))))
3903
            if (bgp_handle_message(p, data, len, &t))
3904
                goto done;
3905

    
3906
        *t++ = ':';
3907
        *t++ = ' ';
3908
        if (len > 16)
3909
            len = 16;
3910
        for (i=0; i<len; i++)
3911
            t += bsprintf(t, "%02x", data[i]);
3912
    }
3913

    
3914
    done:
3915
    *t = 0;
3916
    const byte *dsc = bgp_error_dsc(code, subcode);
3917
    log(L_REMOTE "%s: %s: %s%s", p->p.name, msg, dsc, argbuf);
3918
}
3919

    
3920
static void
3921
bgp_rx_notification(struct bgp_conn *conn, byte *pkt, uint len)
3922
{
3923
    struct bgp_proto *p = conn->bgp;
3924

    
3925
    if (len < 21)
3926
    { bgp_error(conn, 1, 2, pkt+16, 2); return; }
3927

    
3928
    uint code = pkt[19];
3929
    uint subcode = pkt[20];
3930
    int err = (code != 6);
3931

    
3932
    bgp_log_error(p, BE_BGP_RX, "Received", code, subcode, pkt+21, len-21);
3933
    bgp_store_error(p, conn, BE_BGP_RX, (code << 16) | subcode);
3934

    
3935
    bgp_conn_enter_close_state(conn);
3936
    bgp_schedule_packet(conn, NULL, PKT_SCHEDULE_CLOSE);
3937

    
3938
    if (err)
3939
    {
3940
        bgp_update_startup_delay(p);
3941
        bgp_stop(p, 0, NULL, 0);
3942
    }
3943
}
3944

    
3945
static void
3946
bgp_rx_keepalive(struct bgp_conn *conn)
3947
{
3948
    struct bgp_proto *p = conn->bgp;
3949

    
3950
    BGP_TRACE(D_PACKETS, "Got KEEPALIVE");
3951
    bgp_start_timer(conn->hold_timer, conn->hold_time);
3952

    
3953
    if (conn->state == BS_OPENCONFIRM)
3954
    { bgp_conn_enter_established_state(conn); return; }
3955

    
3956
    if (conn->state != BS_ESTABLISHED)
3957
        bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0);
3958
}
3959

    
3960

    
3961
/**
3962
 * bgp_rx_packet - handle a received packet
3963
 * @conn: BGP connection
3964
 * @pkt: start of the packet
3965
 * @len: packet size
3966
 *
3967
 * bgp_rx_packet() takes a newly received packet and calls the corresponding
3968
 * packet handler according to the packet type.
3969
 */
3970
static void
3971
bgp_rx_packet(struct bgp_conn *conn, byte *pkt, uint len)
3972
{
3973
    byte type = pkt[18];
3974

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

    
3977
    if (conn->bgp->p.mrtdump & MD_MESSAGES)
3978
        mrt_dump_bgp_packet(conn, pkt, len);
3979

    
3980
    switch (type)
3981
    {
3982
        case PKT_OPEN:                return bgp_rx_open(conn, pkt, len);
3983
        case PKT_UPDATE:                return bgp_rx_update(conn, pkt, len);
3984
        case PKT_NOTIFICATION:        return bgp_rx_notification(conn, pkt, len);
3985
        case PKT_KEEPALIVE:                return bgp_rx_keepalive(conn);
3986
        case PKT_ROUTE_REFRESH:        return bgp_rx_route_refresh(conn, pkt, len);
3987
        default:                        bgp_error(conn, 1, 3, pkt+18, 1);
3988
    }
3989
}
3990

    
3991
/**
3992
 * bgp_rx - handle received data
3993
 * @sk: socket
3994
 * @size: amount of data received
3995
 *
3996
 * bgp_rx() is called by the socket layer whenever new data arrive from
3997
 * the underlying TCP connection. It assembles the data fragments to packets,
3998
 * checks their headers and framing and passes complete packets to
3999
 * bgp_rx_packet().
4000
 */
4001
int
4002
bgp_rx(sock *sk, uint size)
4003
{
4004
    struct bgp_conn *conn = sk->data;
4005
    byte *pkt_start = sk->rbuf;
4006
    byte *end = pkt_start + size;
4007
    uint i, len;
4008

    
4009
    DBG("BGP: RX hook: Got %d bytes\n", size);
4010
    while (end >= pkt_start + BGP_HEADER_LENGTH)
4011
    {
4012
        if ((conn->state == BS_CLOSE) || (conn->sk != sk))
4013
            return 0;
4014
        for(i=0; i<16; i++)
4015
            if (pkt_start[i] != 0xff)
4016
            {
4017
                bgp_error(conn, 1, 1, NULL, 0);
4018
                break;
4019
            }
4020
        len = get_u16(pkt_start+16);
4021
        if ((len < BGP_HEADER_LENGTH) || (len > bgp_max_packet_length(conn)))
4022
        {
4023
            bgp_error(conn, 1, 2, pkt_start+16, 2);
4024
            break;
4025
        }
4026
        if (end < pkt_start + len)
4027
            break;
4028
        bgp_rx_packet(conn, pkt_start, len);
4029
        pkt_start += len;
4030
    }
4031
    if (pkt_start != sk->rbuf)
4032
    {
4033
        memmove(sk->rbuf, pkt_start, end - pkt_start);
4034
        sk->rpos = sk->rbuf + (end - pkt_start);
4035
    }
4036
    return 0;
4037
}