Revision 42a0c054 nest/a-set.c

View differences:

nest/a-set.c
36 36
{
37 37
  u32 *z = (u32 *) set->data;
38 38
  byte *end = buf + size - 24;
39
  int from2 = MAX(from, 0);
39 40
  int to = set->length / 4;
40 41
  int i;
41 42

  
42
  for (i = MAX(from, 0); i < to; i++)
43
  for (i = from2; i < to; i++)
43 44
    {
44 45
      if (buf > end)
45 46
	{
......
50 51
	  return i;
51 52
	}
52 53

  
53
      if (i > from)
54
      if (i > from2)
54 55
	*buf++ = ' ';
55 56

  
56 57
      if (way)
......
63 64
}
64 65

  
65 66
int
67
ec_format(byte *buf, u64 ec)
68
{
69
  u32 type, key, val;
70
  char tbuf[16], *kind;
71

  
72
  type = ec >> 48;
73
  switch (type & 0xf0ff)
74
    {
75
    case EC_RT: kind = "rt"; break;
76
    case EC_RO: kind = "ro"; break;
77

  
78
    default:
79
      kind = tbuf;
80
      bsprintf(kind, "unknown 0x%x", type);
81
    }
82

  
83
  switch (ec >> 56)
84
    {
85
      /* RFC 4360 3.1.  Two-Octet AS Specific Extended Community */
86
    case 0x00:
87
    case 0x40:
88
      key = (ec >> 32) & 0xFFFF;
89
      val = ec;
90
      return bsprintf(buf, "(%s, %u, %u)", kind, key, val);
91

  
92
      /* RFC 4360 3.2.  IPv4 Address Specific Extended Community */
93
    case 0x01:
94
    case 0x41:
95
      key = ec >> 16;
96
      val = ec & 0xFFFF;
97
      return bsprintf(buf, "(%s, %R, %u)", kind, key, val);
98

  
99
      /* RFC 5668  4-Octet AS Specific BGP Extended Community */
100
    case 0x02:
101
    case 0x42:
102
      key = ec >> 16;
103
      val = ec & 0xFFFF;
104
      return bsprintf(buf, "(%s, %u, %u)", kind, key, val);
105

  
106
      /* Generic format for unknown kinds of extended communities */
107
    default:
108
      key = ec >> 32;
109
      val = ec;
110
      return bsprintf(buf, "(generic, 0x%x, 0x%x)", key, val);
111
    }
112

  
113
}
114

  
115
int
116
ec_set_format(struct adata *set, int from, byte *buf, unsigned int size)
117
{
118
  u32 *z = int_set_get_data(set);
119
  byte *end = buf + size - 24;
120
  int from2 = MAX(from, 0);
121
  int to = int_set_get_size(set);
122
  int i;
123

  
124
  for (i = from2; i < to; i += 2)
125
    {
126
      if (buf > end)
127
	{
128
	  if (from < 0)
129
	    strcpy(buf, " ...");
130
	  else
131
	    *buf = 0;
132
	  return i;
133
	}
134

  
135
      if (i > from2)
136
	*buf++ = ' ';
137

  
138
      buf += ec_format(buf, ec_get(z, i));
139
    }
140
  *buf = 0;
141
  return 0;
142
}
143

  
144
int
66 145
int_set_contains(struct adata *list, u32 val)
67 146
{
68 147
  if (!list)
69 148
    return 0;
70 149

  
71 150
  u32 *l = (u32 *) list->data;
72
  unsigned int i;
73
  for (i=0; i<list->length/4; i++)
151
  int len = int_set_get_size(list);
152
  int i;
153

  
154
  for (i = 0; i < len; i++)
74 155
    if (*l++ == val)
75 156
      return 1;
157

  
158
  return 0;
159
}
160

  
161
int
162
ec_set_contains(struct adata *list, u64 val)
163
{
164
  if (!list)
165
    return 0;
166

  
167
  u32 *l = int_set_get_data(list);
168
  int len = int_set_get_size(list);
169
  u32 eh = ec_hi(val);
170
  u32 el = ec_lo(val);
171
  int i;
172

  
173
  for (i=0; i < len; i += 2)
174
    if (l[i] == eh && l[i+1] == el)
175
      return 1;
176

  
76 177
  return 0;
77 178
}
78 179

  
......
86 187
    return list;
87 188

  
88 189
  len = list ? list->length : 0;
89
  res = lp_alloc(pool, len + sizeof(struct adata) + 4);
190
  res = lp_alloc(pool, sizeof(struct adata) + len + 4);
90 191
  res->length = len + 4;
91 192
  * (u32 *) res->data = val;
92 193
  if (list)
......
95 196
}
96 197

  
97 198
struct adata *
98
int_set_del(struct linpool *pool, struct adata *list, u32 val)
199
ec_set_add(struct linpool *pool, struct adata *list, u64 val)
99 200
{
100
  struct adata *res;
101
  u32 *l, *k;
102
  unsigned int i;
201
  if (ec_set_contains(list, val))
202
    return list;
203

  
204
  int olen = list ? list->length : 0;
205
  struct adata *res = lp_alloc(pool, sizeof(struct adata) + olen + 8);
206
  res->length = olen + 8;
207

  
208
  if (list)
209
    memcpy(res->data, list->data, list->length);
210

  
211
  u32 *l = (u32 *) (res->data + res->length - 8);
212
  l[0] = ec_hi(val);
213
  l[1] = ec_lo(val);
214

  
215
  return res;
216
}
217

  
103 218

  
219
struct adata *
220
int_set_del(struct linpool *pool, struct adata *list, u32 val)
221
{
104 222
  if (!int_set_contains(list, val))
105 223
    return list;
106 224

  
107
  res = lp_alloc(pool, list->length + sizeof(struct adata) - 4);
108
  res->length = list->length-4;
225
  struct adata *res;
226
  res = lp_alloc(pool, sizeof(struct adata) + list->length - 4);
227
  res->length = list->length - 4;
228

  
229
  u32 *l = int_set_get_data(list);
230
  u32 *k = int_set_get_data(res);
231
  int len = int_set_get_size(list);
232
  int i;
109 233

  
110
  l = (u32 *) list->data;
111
  k = (u32 *) res->data;
112
  for (i=0; i<list->length/4; i++)
234
  for (i = 0; i < len; i++)
113 235
    if (l[i] != val)
114 236
      *k++ = l[i];
115 237

  
116 238
  return res;
117 239
}
240

  
241
struct adata *
242
ec_set_del(struct linpool *pool, struct adata *list, u64 val)
243
{
244
  if (!ec_set_contains(list, val))
245
    return list;
246

  
247
  struct adata *res;
248
  res = lp_alloc(pool, sizeof(struct adata) + list->length - 8);
249
  res->length = list->length - 8;
250

  
251
  u32 *l = int_set_get_data(list);
252
  u32 *k = int_set_get_data(res);
253
  int len = int_set_get_size(list);
254
  u32 eh = ec_hi(val);
255
  u32 el = ec_lo(val);
256
  int i;
257

  
258
  for (i=0; i < len; i += 2)
259
    if (! (l[i] == eh && l[i+1] == el))
260
      {
261
	*k++ = l[i];
262
	*k++ = l[i+1];
263
      }
264

  
265
  return res;
266
}

Also available in: Unified diff