Coverage Report

Created: 2025-12-05 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/bgpd/bgp_encap_tlv.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * Copyright 2015, LabN Consulting, L.L.C.
4
 */
5
6
#include <zebra.h>
7
8
#include "command.h"
9
#include "memory.h"
10
#include "prefix.h"
11
#include "filter.h"
12
#include "stream.h"
13
14
#include "bgpd.h"
15
#include "bgp_attr.h"
16
17
#include "bgp_encap_types.h"
18
#include "bgp_encap_tlv.h"
19
20
/***********************************************************************
21
 *      SUBTLV ENCODE
22
 ***********************************************************************/
23
24
/* rfc5512 4.1 */
25
static struct bgp_attr_encap_subtlv *subtlv_encode_encap_l2tpv3_over_ip(
26
  struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)
27
0
{
28
0
  struct bgp_attr_encap_subtlv *new;
29
0
  uint8_t *p;
30
0
  int total = 4 + st->cookie_length;
31
32
  /* sanity check */
33
0
  assert(st->cookie_length <= sizeof(st->cookie));
34
0
  assert(total <= 0xff);
35
36
0
  new = XCALLOC(MTYPE_ENCAP_TLV,
37
0
          sizeof(struct bgp_attr_encap_subtlv) + total);
38
0
  assert(new);
39
0
  new->type = BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION;
40
0
  new->length = total;
41
0
  p = new->value;
42
43
0
  *p++ = (st->sessionid & 0xff000000) >> 24;
44
0
  *p++ = (st->sessionid & 0xff0000) >> 16;
45
0
  *p++ = (st->sessionid & 0xff00) >> 8;
46
0
  *p++ = (st->sessionid & 0xff);
47
0
  memcpy(p, st->cookie, st->cookie_length);
48
0
  return new;
49
0
}
50
51
/* rfc5512 4.1 */
52
static struct bgp_attr_encap_subtlv *
53
subtlv_encode_encap_gre(struct bgp_tea_subtlv_encap_gre_key *st)
54
0
{
55
0
  struct bgp_attr_encap_subtlv *new;
56
0
  uint8_t *p;
57
0
  int total = 4;
58
59
0
  assert(total <= 0xff);
60
61
0
  new = XCALLOC(MTYPE_ENCAP_TLV,
62
0
          sizeof(struct bgp_attr_encap_subtlv) + total);
63
0
  assert(new);
64
0
  new->type = BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION;
65
0
  new->length = total;
66
0
  p = new->value;
67
68
0
  *p++ = (st->gre_key & 0xff000000) >> 24;
69
0
  *p++ = (st->gre_key & 0xff0000) >> 16;
70
0
  *p++ = (st->gre_key & 0xff00) >> 8;
71
0
  *p++ = (st->gre_key & 0xff);
72
0
  return new;
73
0
}
74
75
static struct bgp_attr_encap_subtlv *
76
subtlv_encode_encap_pbb(struct bgp_tea_subtlv_encap_pbb *st)
77
0
{
78
0
  struct bgp_attr_encap_subtlv *new;
79
0
  uint8_t *p;
80
0
  int total = 1 + 3 + 6 + 2; /* flags + isid + madaddr + vid */
81
82
0
  assert(total <= 0xff);
83
84
0
  new = XCALLOC(MTYPE_ENCAP_TLV,
85
0
          sizeof(struct bgp_attr_encap_subtlv) + total);
86
0
  assert(new);
87
0
  new->type = BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION;
88
0
  new->length = total;
89
0
  p = new->value;
90
91
0
  *p++ = (st->flag_isid ? 0x80 : 0) | (st->flag_vid ? 0x40 : 0) | 0;
92
0
  if (st->flag_isid) {
93
0
    *p = (st->isid & 0xff0000) >> 16;
94
0
    *(p + 1) = (st->isid & 0xff00) >> 8;
95
0
    *(p + 2) = (st->isid & 0xff);
96
0
  }
97
0
  p += 3;
98
0
  memcpy(p, st->macaddr, 6);
99
0
  p += 6;
100
0
  if (st->flag_vid) {
101
0
    *p++ = (st->vid & 0xf00) >> 8;
102
0
    *p++ = st->vid & 0xff;
103
0
  }
104
0
  return new;
105
0
}
106
107
/* rfc5512 4.2 */
108
static struct bgp_attr_encap_subtlv *
109
subtlv_encode_proto_type(struct bgp_tea_subtlv_proto_type *st)
110
0
{
111
0
  struct bgp_attr_encap_subtlv *new;
112
0
  uint8_t *p;
113
0
  int total = 2;
114
115
0
  assert(total <= 0xff);
116
117
0
  new = XCALLOC(MTYPE_ENCAP_TLV,
118
0
          sizeof(struct bgp_attr_encap_subtlv) + total);
119
0
  assert(new);
120
0
  new->type = BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE;
121
0
  new->length = total;
122
0
  p = new->value;
123
124
0
  *p++ = (st->proto & 0xff00) >> 8;
125
0
  *p++ = (st->proto & 0xff);
126
0
  return new;
127
0
}
128
129
/* rfc5512 4.3 */
130
static struct bgp_attr_encap_subtlv *
131
subtlv_encode_color(struct bgp_tea_subtlv_color *st)
132
0
{
133
0
  struct bgp_attr_encap_subtlv *new;
134
0
  uint8_t *p;
135
0
  int total = 8;
136
137
0
  assert(total <= 0xff);
138
139
0
  new = XCALLOC(MTYPE_ENCAP_TLV,
140
0
          sizeof(struct bgp_attr_encap_subtlv) + total);
141
0
  assert(new);
142
0
  new->type = BGP_ENCAP_SUBTLV_TYPE_COLOR;
143
0
  new->length = total;
144
0
  p = new->value;
145
146
0
  *p++ = 0x03; /* transitive*/
147
0
  *p++ = 0x0b;
148
0
  *p++ = 0; /* reserved */
149
0
  *p++ = 0; /* reserved */
150
151
0
  *p++ = (st->color & 0xff000000) >> 24;
152
0
  *p++ = (st->color & 0xff0000) >> 16;
153
0
  *p++ = (st->color & 0xff00) >> 8;
154
0
  *p++ = (st->color & 0xff);
155
156
0
  return new;
157
0
}
158
159
/* rfc 5566 4. */
160
static struct bgp_attr_encap_subtlv *
161
subtlv_encode_ipsec_ta(struct bgp_tea_subtlv_ipsec_ta *st)
162
0
{
163
0
  struct bgp_attr_encap_subtlv *new;
164
0
  uint8_t *p;
165
0
  int total = 2 + st->authenticator_length;
166
167
  /* sanity check */
168
0
  assert(st->authenticator_length <= sizeof(st->value));
169
0
  assert(total <= 0xff);
170
171
0
  new = XCALLOC(MTYPE_ENCAP_TLV,
172
0
          sizeof(struct bgp_attr_encap_subtlv) + total);
173
0
  assert(new);
174
0
  new->type = BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA;
175
0
  new->length = total;
176
0
  p = new->value;
177
178
0
  *p++ = (st->authenticator_type & 0xff00) >> 8;
179
0
  *p++ = st->authenticator_type & 0xff;
180
0
  memcpy(p, st->value, st->authenticator_length);
181
0
  return new;
182
0
}
183
184
/* draft-rosen-idr-tunnel-encaps 2.1 */
185
static struct bgp_attr_encap_subtlv *
186
subtlv_encode_remote_endpoint(struct bgp_tea_subtlv_remote_endpoint *st)
187
0
{
188
0
  struct bgp_attr_encap_subtlv *new;
189
0
  uint8_t *p;
190
191
0
  int total = (st->family == AF_INET ? 8 : 20);
192
193
0
  assert(total <= 0xff);
194
195
0
  new = XCALLOC(MTYPE_ENCAP_TLV,
196
0
          sizeof(struct bgp_attr_encap_subtlv) + total);
197
0
  assert(new);
198
0
  new->type = BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT;
199
0
  new->length = total;
200
0
  p = new->value;
201
0
  if (st->family == AF_INET) {
202
0
    memcpy(p, &(st->ip_address.v4.s_addr), IPV4_MAX_BYTELEN);
203
0
    p += IPV4_MAX_BYTELEN;
204
0
  } else {
205
0
    assert(st->family == AF_INET6);
206
0
    memcpy(p, &(st->ip_address.v6.s6_addr), IPV6_MAX_BYTELEN);
207
0
    p += IPV6_MAX_BYTELEN;
208
0
  }
209
0
  memcpy(p, &(st->as4), 4);
210
0
  return new;
211
0
}
212
213
/***********************************************************************
214
 *    TUNNEL TYPE-SPECIFIC TLV ENCODE
215
 ***********************************************************************/
216
217
/*
218
 * requires "extra" and "last" to be defined in caller
219
 */
220
#define ENC_SUBTLV(flag, function, field)                                      \
221
0
  do {                                                                   \
222
0
    struct bgp_attr_encap_subtlv *new;                             \
223
0
    if (CHECK_FLAG(bet->valid_subtlvs, (flag))) {                  \
224
0
      new = function(&bet->field);                           \
225
0
      if (last) {                                            \
226
0
        last->next = new;                              \
227
0
      } else {                                               \
228
0
        attr->encap_subtlvs = new;                     \
229
0
      }                                                      \
230
0
      last = new;                                            \
231
0
    }                                                              \
232
0
  } while (0)
233
234
void bgp_encap_type_l2tpv3overip_to_tlv(
235
  struct bgp_encap_type_l2tpv3_over_ip *bet, /* input structure */
236
  struct attr *attr)
237
0
{
238
0
  struct bgp_attr_encap_subtlv *last;
239
240
  /* advance to last subtlv */
241
0
  for (last = attr->encap_subtlvs; last && last->next; last = last->next)
242
0
    ;
243
244
0
  attr->encap_tunneltype = BGP_ENCAP_TYPE_L2TPV3_OVER_IP;
245
246
0
  assert(CHECK_FLAG(bet->valid_subtlvs, BGP_TEA_SUBTLV_ENCAP));
247
248
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_ENCAP, subtlv_encode_encap_l2tpv3_over_ip,
249
0
       st_encap);
250
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_PROTO_TYPE, subtlv_encode_proto_type,
251
0
       st_proto);
252
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_COLOR, subtlv_encode_color, st_color);
253
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_REMOTE_ENDPOINT,
254
0
       subtlv_encode_remote_endpoint, st_endpoint);
255
0
}
256
257
void bgp_encap_type_gre_to_tlv(
258
  struct bgp_encap_type_gre *bet, /* input structure */
259
  struct attr *attr)
260
0
{
261
0
  struct bgp_attr_encap_subtlv *last;
262
263
  /* advance to last subtlv */
264
0
  for (last = attr->encap_subtlvs; last && last->next; last = last->next)
265
0
    ;
266
267
0
  attr->encap_tunneltype = BGP_ENCAP_TYPE_GRE;
268
269
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_ENCAP, subtlv_encode_encap_gre, st_encap);
270
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_PROTO_TYPE, subtlv_encode_proto_type,
271
0
       st_proto);
272
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_COLOR, subtlv_encode_color, st_color);
273
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_REMOTE_ENDPOINT,
274
0
       subtlv_encode_remote_endpoint, st_endpoint);
275
0
}
276
277
void bgp_encap_type_ip_in_ip_to_tlv(
278
  struct bgp_encap_type_ip_in_ip *bet, /* input structure */
279
  struct attr *attr)
280
0
{
281
0
  struct bgp_attr_encap_subtlv *last;
282
283
  /* advance to last subtlv */
284
0
  for (last = attr->encap_subtlvs; last && last->next; last = last->next)
285
0
    ;
286
287
0
  attr->encap_tunneltype = BGP_ENCAP_TYPE_IP_IN_IP;
288
289
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_PROTO_TYPE, subtlv_encode_proto_type,
290
0
       st_proto);
291
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_COLOR, subtlv_encode_color, st_color);
292
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_REMOTE_ENDPOINT,
293
0
       subtlv_encode_remote_endpoint, st_endpoint);
294
0
}
295
296
void bgp_encap_type_transmit_tunnel_endpoint(
297
  struct bgp_encap_type_transmit_tunnel_endpoint
298
    *bet, /* input structure */
299
  struct attr *attr)
300
0
{
301
0
  struct bgp_attr_encap_subtlv *last;
302
303
  /* advance to last subtlv */
304
0
  for (last = attr->encap_subtlvs; last && last->next; last = last->next)
305
0
    ;
306
307
0
  attr->encap_tunneltype = BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT;
308
309
  /* no subtlvs for this type */
310
0
}
311
312
void bgp_encap_type_ipsec_in_tunnel_mode_to_tlv(
313
  struct bgp_encap_type_ipsec_in_tunnel_mode *bet, /* input structure */
314
  struct attr *attr)
315
0
{
316
0
  struct bgp_attr_encap_subtlv *last;
317
318
  /* advance to last subtlv */
319
0
  for (last = attr->encap_subtlvs; last && last->next; last = last->next)
320
0
    ;
321
322
0
  attr->encap_tunneltype = BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE;
323
324
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta,
325
0
       st_ipsec_ta);
326
0
}
327
328
void bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
329
  struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode
330
    *bet, /* input structure */
331
  struct attr *attr)
332
0
{
333
0
  struct bgp_attr_encap_subtlv *last;
334
335
  /* advance to last subtlv */
336
0
  for (last = attr->encap_subtlvs; last && last->next; last = last->next)
337
0
    ;
338
339
0
  attr->encap_tunneltype =
340
0
    BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE;
341
342
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta,
343
0
       st_ipsec_ta);
344
0
}
345
346
void bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
347
  struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode
348
    *bet, /* input structure */
349
  struct attr *attr)
350
0
{
351
0
  struct bgp_attr_encap_subtlv *last;
352
353
  /* advance to last subtlv */
354
0
  for (last = attr->encap_subtlvs; last && last->next; last = last->next)
355
0
    ;
356
357
0
  attr->encap_tunneltype =
358
0
    BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE;
359
360
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta,
361
0
       st_ipsec_ta);
362
0
}
363
364
void bgp_encap_type_pbb_to_tlv(
365
  struct bgp_encap_type_pbb *bet, /* input structure */
366
  struct attr *attr)
367
0
{
368
0
  struct bgp_attr_encap_subtlv *last;
369
370
  /* advance to last subtlv */
371
0
  for (last = attr->encap_subtlvs; last && last->next; last = last->next)
372
0
    ;
373
374
0
  attr->encap_tunneltype = BGP_ENCAP_TYPE_PBB;
375
376
0
  assert(CHECK_FLAG(bet->valid_subtlvs, BGP_TEA_SUBTLV_ENCAP));
377
0
  ENC_SUBTLV(BGP_TEA_SUBTLV_ENCAP, subtlv_encode_encap_pbb, st_encap);
378
0
}
379
380
void bgp_encap_type_vxlan_to_tlv(
381
  struct bgp_encap_type_vxlan *bet, /* input structure */
382
  struct attr *attr)
383
0
{
384
0
  struct bgp_attr_encap_subtlv *tlv;
385
0
  uint32_t vnid;
386
387
0
  attr->encap_tunneltype = BGP_ENCAP_TYPE_VXLAN;
388
389
0
  if (bet == NULL || !bet->vnid)
390
0
    return;
391
0
  XFREE(MTYPE_ENCAP_TLV, attr->encap_subtlvs);
392
0
  tlv = XCALLOC(MTYPE_ENCAP_TLV,
393
0
          sizeof(struct bgp_attr_encap_subtlv) + 12);
394
0
  tlv->type = 1; /* encapsulation type */
395
0
  tlv->length = 12;
396
0
  if (bet->vnid) {
397
0
    vnid = htonl(bet->vnid | VXLAN_ENCAP_MASK_VNID_VALID);
398
0
    memcpy(&tlv->value, &vnid, 4);
399
0
  }
400
0
  if (bet->mac_address) {
401
0
    char *ptr = (char *)&tlv->value + 4;
402
0
    memcpy(ptr, bet->mac_address, 6);
403
0
  }
404
0
  attr->encap_subtlvs = tlv;
405
0
  return;
406
0
}
407
408
void bgp_encap_type_nvgre_to_tlv(
409
  struct bgp_encap_type_nvgre *bet, /* input structure */
410
  struct attr *attr)
411
0
{
412
0
  attr->encap_tunneltype = BGP_ENCAP_TYPE_NVGRE;
413
0
}
414
415
void bgp_encap_type_mpls_to_tlv(
416
  struct bgp_encap_type_mpls *bet, /* input structure */
417
  struct attr *attr)
418
0
{
419
0
  return; /* no encap attribute for MPLS */
420
0
}
421
422
void bgp_encap_type_mpls_in_gre_to_tlv(
423
  struct bgp_encap_type_mpls_in_gre *bet, /* input structure */
424
  struct attr *attr)
425
0
{
426
0
  attr->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_GRE;
427
0
}
428
429
void bgp_encap_type_vxlan_gpe_to_tlv(
430
  struct bgp_encap_type_vxlan_gpe *bet, /* input structure */
431
  struct attr *attr)
432
0
{
433
434
0
  attr->encap_tunneltype = BGP_ENCAP_TYPE_VXLAN_GPE;
435
0
}
436
437
void bgp_encap_type_mpls_in_udp_to_tlv(
438
  struct bgp_encap_type_mpls_in_udp *bet, /* input structure */
439
  struct attr *attr)
440
0
{
441
442
0
  attr->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_UDP;
443
0
}
444
445
446
/***********************************************************************
447
 *      SUBTLV DECODE
448
 ***********************************************************************/
449
/* rfc5512 4.1 */
450
static int subtlv_decode_encap_l2tpv3_over_ip(
451
  struct bgp_attr_encap_subtlv *subtlv,
452
  struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)
453
0
{
454
0
  if (subtlv->length < 4) {
455
0
    zlog_debug("%s, subtlv length %d is less than 4", __func__,
456
0
         subtlv->length);
457
0
    return -1;
458
0
  }
459
460
0
  ptr_get_be32(subtlv->value, &st->sessionid);
461
0
  st->cookie_length = subtlv->length - 4;
462
0
  if (st->cookie_length > sizeof(st->cookie)) {
463
0
    zlog_debug("%s, subtlv length %d is greater than %d", __func__,
464
0
         st->cookie_length, (int)sizeof(st->cookie));
465
0
    return -1;
466
0
  }
467
0
  memcpy(st->cookie, subtlv->value + 4, st->cookie_length);
468
0
  return 0;
469
0
}
470
471
/* rfc5512 4.1 */
472
static int subtlv_decode_encap_gre(struct bgp_attr_encap_subtlv *subtlv,
473
           struct bgp_tea_subtlv_encap_gre_key *st)
474
0
{
475
0
  if (subtlv->length != 4) {
476
0
    zlog_debug("%s, subtlv length %d does not equal 4", __func__,
477
0
         subtlv->length);
478
0
    return -1;
479
0
  }
480
0
  ptr_get_be32(subtlv->value, &st->gre_key);
481
0
  return 0;
482
0
}
483
484
static int subtlv_decode_encap_pbb(struct bgp_attr_encap_subtlv *subtlv,
485
           struct bgp_tea_subtlv_encap_pbb *st)
486
0
{
487
0
  if (subtlv->length != 1 + 3 + 6 + 2) {
488
0
    zlog_debug("%s, subtlv length %d does not equal %d", __func__,
489
0
         subtlv->length, 1 + 3 + 6 + 2);
490
0
    return -1;
491
0
  }
492
0
  if (subtlv->value[0] & 0x80) {
493
0
    st->flag_isid = 1;
494
0
    st->isid = (subtlv->value[1] << 16) | (subtlv->value[2] << 8)
495
0
         | subtlv->value[3];
496
0
  }
497
0
  if (subtlv->value[0] & 0x40) {
498
0
    st->flag_vid = 1;
499
0
    st->vid = ((subtlv->value[10] & 0x0f) << 8) | subtlv->value[11];
500
0
  }
501
0
  memcpy(st->macaddr, subtlv->value + 4, 6);
502
0
  return 0;
503
0
}
504
505
/* rfc5512 4.2 */
506
static int subtlv_decode_proto_type(struct bgp_attr_encap_subtlv *subtlv,
507
            struct bgp_tea_subtlv_proto_type *st)
508
0
{
509
0
  if (subtlv->length != 2) {
510
0
    zlog_debug("%s, subtlv length %d does not equal 2", __func__,
511
0
         subtlv->length);
512
0
    return -1;
513
0
  }
514
0
  st->proto = (subtlv->value[0] << 8) | subtlv->value[1];
515
0
  return 0;
516
0
}
517
518
/* rfc5512 4.3 */
519
static int subtlv_decode_color(struct bgp_attr_encap_subtlv *subtlv,
520
             struct bgp_tea_subtlv_color *st)
521
0
{
522
0
  if (subtlv->length != 8) {
523
0
    zlog_debug("%s, subtlv length %d does not equal 8", __func__,
524
0
         subtlv->length);
525
0
    return -1;
526
0
  }
527
0
  if ((subtlv->value[0] != 0x03) || (subtlv->value[1] != 0x0b)
528
0
      || (subtlv->value[2] != 0) || (subtlv->value[3] != 0)) {
529
0
    zlog_debug("%s, subtlv value 1st 4 bytes are not 0x030b0000",
530
0
         __func__);
531
0
    return -1;
532
0
  }
533
0
  ptr_get_be32(subtlv->value + 4, &st->color);
534
0
  return 0;
535
0
}
536
537
/* rfc 5566 4. */
538
static int subtlv_decode_ipsec_ta(struct bgp_attr_encap_subtlv *subtlv,
539
          struct bgp_tea_subtlv_ipsec_ta *st)
540
0
{
541
0
  st->authenticator_length = subtlv->length - 2;
542
0
  if (st->authenticator_length > sizeof(st->value)) {
543
0
    zlog_debug(
544
0
      "%s, authenticator length %d exceeds storage maximum %d",
545
0
      __func__, st->authenticator_length,
546
0
      (int)sizeof(st->value));
547
0
    return -1;
548
0
  }
549
0
  st->authenticator_type = (subtlv->value[0] << 8) | subtlv->value[1];
550
0
  memcpy(st->value, subtlv->value + 2, st->authenticator_length);
551
0
  return 0;
552
0
}
553
554
/* draft-rosen-idr-tunnel-encaps 2.1 */
555
static int
556
subtlv_decode_remote_endpoint(struct bgp_attr_encap_subtlv *subtlv,
557
            struct bgp_tea_subtlv_remote_endpoint *st)
558
0
{
559
0
  int i;
560
0
  if (subtlv->length != 8 && subtlv->length != 20) {
561
0
    zlog_debug("%s, subtlv length %d does not equal 8 or 20",
562
0
         __func__, subtlv->length);
563
0
    return -1;
564
0
  }
565
0
  if (subtlv->length == 8) {
566
0
    st->family = AF_INET;
567
0
    memcpy(&st->ip_address.v4.s_addr, subtlv->value,
568
0
           IPV4_MAX_BYTELEN);
569
0
  } else {
570
0
    st->family = AF_INET6;
571
0
    memcpy(&(st->ip_address.v6.s6_addr), subtlv->value,
572
0
           IPV6_MAX_BYTELEN);
573
0
  }
574
0
  i = subtlv->length - 4;
575
0
  ptr_get_be32(subtlv->value + i, &st->as4);
576
0
  return 0;
577
0
}
578
579
/***********************************************************************
580
 *    TUNNEL TYPE-SPECIFIC TLV DECODE
581
 ***********************************************************************/
582
583
int tlv_to_bgp_encap_type_l2tpv3overip(
584
  struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
585
  struct bgp_encap_type_l2tpv3_over_ip *bet) /* caller-allocated */
586
0
{
587
0
  struct bgp_attr_encap_subtlv *st;
588
0
  int rc = 0;
589
590
0
  for (st = stlv; st; st = st->next) {
591
0
    switch (st->type) {
592
0
    case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
593
0
      rc |= subtlv_decode_encap_l2tpv3_over_ip(
594
0
        st, &bet->st_encap);
595
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
596
0
      break;
597
598
0
    case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
599
0
      rc |= subtlv_decode_proto_type(st, &bet->st_proto);
600
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
601
0
      break;
602
603
0
    case BGP_ENCAP_SUBTLV_TYPE_COLOR:
604
0
      rc |= subtlv_decode_color(st, &bet->st_color);
605
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
606
0
      break;
607
608
0
    case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
609
0
      rc |= subtlv_decode_remote_endpoint(st,
610
0
                  &bet->st_endpoint);
611
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
612
0
      break;
613
614
0
    default:
615
0
      zlog_debug("%s: unexpected subtlv type %d", __func__,
616
0
           st->type);
617
0
      rc |= -1;
618
0
      break;
619
0
    }
620
0
  }
621
0
  return rc;
622
0
}
623
624
int tlv_to_bgp_encap_type_gre(
625
  struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
626
  struct bgp_encap_type_gre *bet)     /* caller-allocated */
627
0
{
628
0
  struct bgp_attr_encap_subtlv *st;
629
0
  int rc = 0;
630
631
0
  for (st = stlv; st; st = st->next) {
632
0
    switch (st->type) {
633
0
    case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
634
0
      rc |= subtlv_decode_encap_gre(st, &bet->st_encap);
635
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
636
0
      break;
637
638
0
    case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
639
0
      rc |= subtlv_decode_proto_type(st, &bet->st_proto);
640
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
641
0
      break;
642
643
0
    case BGP_ENCAP_SUBTLV_TYPE_COLOR:
644
0
      rc |= subtlv_decode_color(st, &bet->st_color);
645
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
646
0
      break;
647
648
0
    case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
649
0
      rc |= subtlv_decode_remote_endpoint(st,
650
0
                  &bet->st_endpoint);
651
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
652
0
      break;
653
654
0
    default:
655
0
      zlog_debug("%s: unexpected subtlv type %d", __func__,
656
0
           st->type);
657
0
      rc |= -1;
658
0
      break;
659
0
    }
660
0
  }
661
0
  return rc;
662
0
}
663
664
int tlv_to_bgp_encap_type_ip_in_ip(
665
  struct bgp_attr_encap_subtlv *stlv,  /* subtlv chain */
666
  struct bgp_encap_type_ip_in_ip *bet) /* caller-allocated */
667
0
{
668
0
  struct bgp_attr_encap_subtlv *st;
669
0
  int rc = 0;
670
671
0
  for (st = stlv; st; st = st->next) {
672
0
    switch (st->type) {
673
0
    case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
674
0
      rc |= subtlv_decode_proto_type(st, &bet->st_proto);
675
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
676
0
      break;
677
678
0
    case BGP_ENCAP_SUBTLV_TYPE_COLOR:
679
0
      rc |= subtlv_decode_color(st, &bet->st_color);
680
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
681
0
      break;
682
683
0
    case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
684
0
      rc |= subtlv_decode_remote_endpoint(st,
685
0
                  &bet->st_endpoint);
686
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
687
0
      break;
688
689
0
    default:
690
0
      zlog_debug("%s: unexpected subtlv type %d", __func__,
691
0
           st->type);
692
0
      rc |= -1;
693
0
      break;
694
0
    }
695
0
  }
696
0
  return rc;
697
0
}
698
699
int tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
700
  struct bgp_attr_encap_subtlv *stlv,
701
  struct bgp_encap_type_transmit_tunnel_endpoint *bet)
702
0
{
703
0
  struct bgp_attr_encap_subtlv *st;
704
0
  int rc = 0;
705
706
0
  for (st = stlv; st; st = st->next) {
707
0
    switch (st->type) {
708
709
0
    case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
710
0
      rc |= subtlv_decode_remote_endpoint(st,
711
0
                  &bet->st_endpoint);
712
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
713
0
      break;
714
715
0
    default:
716
0
      zlog_debug("%s: unexpected subtlv type %d", __func__,
717
0
           st->type);
718
0
      rc |= -1;
719
0
      break;
720
0
    }
721
0
  }
722
0
  return rc;
723
0
}
724
725
int tlv_to_bgp_encap_type_ipsec_in_tunnel_mode(
726
  struct bgp_attr_encap_subtlv *stlv,    /* subtlv chain */
727
  struct bgp_encap_type_ipsec_in_tunnel_mode *bet) /* caller-allocated */
728
0
{
729
0
  struct bgp_attr_encap_subtlv *st;
730
0
  int rc = 0;
731
732
0
  for (st = stlv; st; st = st->next) {
733
0
    switch (st->type) {
734
0
    case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
735
0
      rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
736
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
737
0
      break;
738
739
0
    case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
740
0
      rc |= subtlv_decode_remote_endpoint(st,
741
0
                  &bet->st_endpoint);
742
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
743
0
      break;
744
745
0
    default:
746
0
      zlog_debug("%s: unexpected subtlv type %d", __func__,
747
0
           st->type);
748
0
      rc |= -1;
749
0
      break;
750
0
    }
751
0
  }
752
0
  return rc;
753
0
}
754
755
int tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
756
  struct bgp_attr_encap_subtlv *stlv,
757
  struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet)
758
0
{
759
0
  struct bgp_attr_encap_subtlv *st;
760
0
  int rc = 0;
761
762
0
  for (st = stlv; st; st = st->next) {
763
0
    switch (st->type) {
764
0
    case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
765
0
      rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
766
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
767
0
      break;
768
769
0
    case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
770
0
      rc |= subtlv_decode_remote_endpoint(st,
771
0
                  &bet->st_endpoint);
772
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
773
0
      break;
774
775
0
    default:
776
0
      zlog_debug("%s: unexpected subtlv type %d", __func__,
777
0
           st->type);
778
0
      rc |= -1;
779
0
      break;
780
0
    }
781
0
  }
782
0
  return rc;
783
0
}
784
785
int tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
786
  struct bgp_attr_encap_subtlv *stlv,
787
  struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet)
788
0
{
789
0
  struct bgp_attr_encap_subtlv *st;
790
0
  int rc = 0;
791
792
0
  for (st = stlv; st; st = st->next) {
793
0
    switch (st->type) {
794
0
    case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
795
0
      rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
796
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
797
0
      break;
798
799
0
    case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
800
0
      rc |= subtlv_decode_remote_endpoint(st,
801
0
                  &bet->st_endpoint);
802
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
803
0
      break;
804
805
0
    default:
806
0
      zlog_debug("%s: unexpected subtlv type %d", __func__,
807
0
           st->type);
808
0
      rc |= -1;
809
0
      break;
810
0
    }
811
0
  }
812
0
  return rc;
813
0
}
814
815
int tlv_to_bgp_encap_type_vxlan(struct bgp_attr_encap_subtlv *stlv,
816
        struct bgp_encap_type_vxlan *bet)
817
0
{
818
0
  struct bgp_attr_encap_subtlv *st;
819
0
  int rc = 0;
820
821
0
  for (st = stlv; st; st = st->next) {
822
0
    switch (st->type) {
823
824
0
    case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
825
0
      rc |= subtlv_decode_remote_endpoint(st,
826
0
                  &bet->st_endpoint);
827
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
828
0
      break;
829
830
0
    default:
831
0
      zlog_debug("%s: unexpected subtlv type %d", __func__,
832
0
           st->type);
833
0
      rc |= -1;
834
0
      break;
835
0
    }
836
0
  }
837
0
  return rc;
838
0
}
839
840
int tlv_to_bgp_encap_type_nvgre(struct bgp_attr_encap_subtlv *stlv,
841
        struct bgp_encap_type_nvgre *bet)
842
0
{
843
0
  struct bgp_attr_encap_subtlv *st;
844
0
  int rc = 0;
845
846
0
  for (st = stlv; st; st = st->next) {
847
0
    switch (st->type) {
848
849
0
    case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
850
0
      rc |= subtlv_decode_remote_endpoint(st,
851
0
                  &bet->st_endpoint);
852
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
853
0
      break;
854
855
0
    default:
856
0
      zlog_debug("%s: unexpected subtlv type %d", __func__,
857
0
           st->type);
858
0
      rc |= -1;
859
0
      break;
860
0
    }
861
0
  }
862
0
  return rc;
863
0
}
864
865
int tlv_to_bgp_encap_type_mpls(struct bgp_attr_encap_subtlv *stlv,
866
             struct bgp_encap_type_mpls *bet)
867
0
{
868
0
  struct bgp_attr_encap_subtlv *st;
869
0
  int rc = 0;
870
871
0
  for (st = stlv; st; st = st->next) {
872
0
    switch (st->type) {
873
874
0
    case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
875
0
      rc |= subtlv_decode_remote_endpoint(st,
876
0
                  &bet->st_endpoint);
877
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
878
0
      break;
879
880
0
    default:
881
0
      zlog_debug("%s: unexpected subtlv type %d", __func__,
882
0
           st->type);
883
0
      rc |= -1;
884
0
      break;
885
0
    }
886
0
  }
887
0
  return rc;
888
0
}
889
890
int tlv_to_bgp_encap_type_mpls_in_gre(struct bgp_attr_encap_subtlv *stlv,
891
              struct bgp_encap_type_mpls_in_gre *bet)
892
0
{
893
0
  struct bgp_attr_encap_subtlv *st;
894
0
  int rc = 0;
895
896
0
  for (st = stlv; st; st = st->next) {
897
0
    switch (st->type) {
898
899
0
    case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
900
0
      rc |= subtlv_decode_remote_endpoint(st,
901
0
                  &bet->st_endpoint);
902
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
903
0
      break;
904
905
0
    default:
906
0
      zlog_debug("%s: unexpected subtlv type %d", __func__,
907
0
           st->type);
908
0
      rc |= -1;
909
0
      break;
910
0
    }
911
0
  }
912
0
  return rc;
913
0
}
914
915
int tlv_to_bgp_encap_type_vxlan_gpe(struct bgp_attr_encap_subtlv *stlv,
916
            struct bgp_encap_type_vxlan_gpe *bet)
917
0
{
918
0
  struct bgp_attr_encap_subtlv *st;
919
0
  int rc = 0;
920
921
0
  for (st = stlv; st; st = st->next) {
922
0
    switch (st->type) {
923
924
0
    case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
925
0
      rc |= subtlv_decode_remote_endpoint(st,
926
0
                  &bet->st_endpoint);
927
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
928
0
      break;
929
930
0
    default:
931
0
      zlog_debug("%s: unexpected subtlv type %d", __func__,
932
0
           st->type);
933
0
      rc |= -1;
934
0
      break;
935
0
    }
936
0
  }
937
0
  return rc;
938
0
}
939
940
int tlv_to_bgp_encap_type_mpls_in_udp(struct bgp_attr_encap_subtlv *stlv,
941
              struct bgp_encap_type_mpls_in_udp *bet)
942
0
{
943
0
  struct bgp_attr_encap_subtlv *st;
944
0
  int rc = 0;
945
946
0
  for (st = stlv; st; st = st->next) {
947
0
    switch (st->type) {
948
949
0
    case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
950
0
      rc |= subtlv_decode_remote_endpoint(st,
951
0
                  &bet->st_endpoint);
952
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
953
0
      break;
954
955
0
    default:
956
0
      zlog_debug("%s: unexpected subtlv type %d", __func__,
957
0
           st->type);
958
0
      rc |= -1;
959
0
      break;
960
0
    }
961
0
  }
962
0
  return rc;
963
0
}
964
965
int tlv_to_bgp_encap_type_pbb(
966
  struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
967
  struct bgp_encap_type_pbb *bet)     /* caller-allocated */
968
0
{
969
0
  struct bgp_attr_encap_subtlv *st;
970
0
  int rc = 0;
971
972
0
  for (st = stlv; st; st = st->next) {
973
0
    switch (st->type) {
974
0
    case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
975
0
      rc |= subtlv_decode_encap_pbb(st, &bet->st_encap);
976
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
977
0
      break;
978
979
0
    case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
980
0
      rc |= subtlv_decode_remote_endpoint(st,
981
0
                  &bet->st_endpoint);
982
0
      SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
983
0
      break;
984
985
0
    default:
986
0
      zlog_debug("%s: unexpected subtlv type %d", __func__,
987
0
           st->type);
988
0
      rc |= -1;
989
0
      break;
990
0
    }
991
0
  }
992
0
  return rc;
993
0
}