attrs.h 6.24 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/*
 *	BIRD Internet Routing Daemon -- Attribute Operations
 *
 *	(c) 2000 Martin Mares <mj@ucw.cz>
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#ifndef _BIRD_ATTRS_H_
#define _BIRD_ATTRS_H_

12
#include <stdint.h>
Ondřej Zajíček's avatar
Ondřej Zajíček committed
13 14 15
#include "lib/unaligned.h"
#include "nest/route.h"

16

17 18
/* a-path.c */

19 20
#define AS_PATH_SET		1	/* Types of path segments */
#define AS_PATH_SEQUENCE	2
21 22
#define AS_PATH_CONFED_SEQUENCE	3
#define AS_PATH_CONFED_SET	4
23

24 25 26 27 28 29 30
#define AS_PATH_MAXLEN		10000

#define AS_TRANS		23456
/* AS_TRANS is used when we need to store 32bit ASN larger than 0xFFFF
 * to 16bit slot (like in 16bit AS_PATH). See RFC 4893 for details
 */

31 32
struct f_tree;

Ondřej Zajíček's avatar
Ondřej Zajíček committed
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
int as_path_valid(byte *data, uint len, int bs, char *err, uint elen);
int as_path_16to32(byte *dst, byte *src, uint len);
int as_path_32to16(byte *dst, byte *src, uint len);
int as_path_contains_as4(const struct adata *path);
int as_path_contains_confed(const struct adata *path);
struct adata *as_path_strip_confed(struct linpool *pool, const struct adata *op);
struct adata *as_path_prepend2(struct linpool *pool, const struct adata *op, int seq, u32 as, int strip);
struct adata *as_path_to_old(struct linpool *pool, const struct adata *path);
void as_path_cut(struct adata *path, uint num);
struct adata *as_path_merge(struct linpool *pool, struct adata *p1, struct adata *p2);
void as_path_format(const struct adata *path, byte *buf, uint size);
int as_path_getlen(const struct adata *path);
int as_path_getlen_int(const struct adata *path, int bs);
int as_path_get_first(const struct adata *path, u32 *orig_as);
int as_path_get_last(const struct adata *path, u32 *last_as);
u32 as_path_get_last_nonaggregated(const struct adata *path);
int as_path_contains(const struct adata *path, u32 as, int min);
int as_path_match_set(const struct adata *path, struct f_tree *set);
51 52
struct adata *as_path_filter(struct linpool *pool, struct adata *path, struct f_tree *set, u32 key, int pos);

Ondřej Zajíček's avatar
Ondřej Zajíček committed
53 54 55
static inline struct adata *as_path_prepend(struct linpool *pool, const struct adata *path, u32 as)
{ return as_path_prepend2(pool, path, AS_PATH_SEQUENCE, as, 0); }

56

57 58 59
#define PM_ASN		0
#define PM_QUESTION	1
#define PM_ASTERISK	2
60
#define PM_ASN_EXPR	3
61
#define PM_ASN_RANGE	4
62

63 64
struct f_path_mask {
  struct f_path_mask *next;
65
  int kind;
66
  uintptr_t val;
67
  uintptr_t val2;
68
};
69

Ondřej Zajíček's avatar
Ondřej Zajíček committed
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
int as_path_match(const struct adata *path, struct f_path_mask *mask);


/* Counterparts to appropriate as_path_* functions */

static inline int
aggregator_16to32(byte *dst, byte *src)
{
  put_u32(dst, get_u16(src));
  memcpy(dst+4, src+2, 4);
  return 8;
}

static inline int
aggregator_32to16(byte *dst, byte *src)
{
  put_u16(dst, get_u32(src));
  memcpy(dst+2, src+4, 4);
  return 6;
}

static inline int
aggregator_contains_as4(struct adata *a)
{
  return get_u32(a->data) > 0xFFFF;
}

static inline struct adata *
aggregator_to_old(struct linpool *pool, struct adata *a)
{
  struct adata *d = lp_alloc_adata(pool, 8);
  put_u32(d->data, 0xFFFF);
  memcpy(d->data + 4, a->data + 4, 4);
  return d;
}

106

107 108
/* a-set.c */

109 110 111 112 113 114 115 116 117 118

/* Extended Community subtypes (kinds) */
#define EC_RT 0x0002
#define EC_RO 0x0003

#define EC_GENERIC 0xFFFF

/* Transitive bit (for first u32 half of EC) */
#define EC_TBIT 0x40000000

119
#define ECOMM_LENGTH 8
120 121 122 123

static inline int int_set_get_size(struct adata *list)
{ return list->length / 4; }

124 125 126
static inline int ec_set_get_size(struct adata *list)
{ return list->length / 8; }

127 128 129
static inline int lc_set_get_size(struct adata *list)
{ return list->length / 12; }

130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
static inline u32 *int_set_get_data(struct adata *list)
{ return (u32 *) list->data; }

static inline u32 ec_hi(u64 ec) { return ec >> 32; }
static inline u32 ec_lo(u64 ec) { return ec; }
static inline u64 ec_get(const u32 *l, int i)
{ return (((u64) l[i]) << 32) | l[i+1]; }

/* RFC 4360 3.1.  Two-Octet AS Specific Extended Community */
static inline u64 ec_as2(u64 kind, u64 key, u64 val)
{ return ((kind | 0x0000) << 48) | (key << 32) | val; }

/* RFC 5668  4-Octet AS Specific BGP Extended Community */
static inline u64 ec_as4(u64 kind, u64 key, u64 val)
{ return ((kind | 0x0200) << 48) | (key << 16) | val; }

/* RFC 4360 3.2.  IPv4 Address Specific Extended Community */
static inline u64 ec_ip4(u64 kind, u64 key, u64 val)
{ return ((kind | 0x0100) << 48) | (key << 16) | val; }

static inline u64 ec_generic(u64 key, u64 val)
{ return (key << 32) | val; }

153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
/* Large community value */
typedef struct lcomm {
  u32 asn;
  u32 ldp1;
  u32 ldp2;
} lcomm;

#define LCOMM_LENGTH 12

static inline lcomm lc_get(const u32 *l, int i)
{ return (lcomm) { l[i], l[i+1], l[i+2] }; }

static inline void lc_put(u32 *l, lcomm v)
{ l[0] = v.asn; l[1] = v.ldp1; l[2] = v.ldp2; }

static inline int lc_match(const u32 *l, int i, lcomm v)
{ return (l[i] == v.asn && l[i+1] == v.ldp1 && l[i+2] == v.ldp2); }

static inline u32 *lc_copy(u32 *dst, const u32 *src)
{ memcpy(dst, src, LCOMM_LENGTH); return dst + 3; }


Pavel Tvrdík's avatar
Pavel Tvrdík committed
175
int int_set_format(struct adata *set, int way, int from, byte *buf, uint size);
176
int ec_format(byte *buf, u64 ec);
Pavel Tvrdík's avatar
Pavel Tvrdík committed
177
int ec_set_format(struct adata *set, int from, byte *buf, uint size);
178 179
int lc_format(byte *buf, lcomm lc);
int lc_set_format(struct adata *set, int from, byte *buf, uint size);
180
int int_set_contains(struct adata *list, u32 val);
181
int ec_set_contains(struct adata *list, u64 val);
182
int lc_set_contains(struct adata *list, lcomm val);
183 184
struct adata *int_set_add(struct linpool *pool, struct adata *list, u32 val);
struct adata *ec_set_add(struct linpool *pool, struct adata *list, u64 val);
185
struct adata *lc_set_add(struct linpool *pool, struct adata *list, lcomm val);
186
struct adata *int_set_del(struct linpool *pool, struct adata *list, u32 val);
187
struct adata *ec_set_del(struct linpool *pool, struct adata *list, u64 val);
188
struct adata *lc_set_del(struct linpool *pool, struct adata *list, lcomm val);
189 190
struct adata *int_set_union(struct linpool *pool, struct adata *l1, struct adata *l2);
struct adata *ec_set_union(struct linpool *pool, struct adata *l1, struct adata *l2);
191
struct adata *lc_set_union(struct linpool *pool, struct adata *l1, struct adata *l2);
192

Ondřej Zajíček's avatar
Ondřej Zajíček committed
193 194 195 196
struct adata *ec_set_del_nontrans(struct linpool *pool, struct adata *set);
struct adata *int_set_sort(struct linpool *pool, struct adata *src);
struct adata *ec_set_sort(struct linpool *pool, struct adata *src);
struct adata *lc_set_sort(struct linpool *pool, struct adata *src);
197

198
#endif