Revision e3558ab1

View differences:

proto/bgp/attrs.c
8 8

  
9 9
#define LOCAL_DEBUG
10 10

  
11
#include <stdlib.h>
12

  
11 13
#include "nest/bird.h"
12 14
#include "nest/iface.h"
13 15
#include "nest/protocol.h"
......
123 125
      eattr *a = &buck->eattrs->attrs[i];
124 126
      ASSERT(EA_PROTO(a->id) == EAP_BGP);
125 127
      code = EA_ID(a->id);
128
      flags = a->flags & (BAF_OPTIONAL | BAF_TRANSITIVE | BAF_PARTIAL);
126 129
      if (code && code < ARRAY_SIZE(bgp_attr_table))
127 130
	{
128 131
	  struct attr_desc *desc = &bgp_attr_table[code];
......
138 141
	  ASSERT((a->type & EAF_TYPE_MASK) == EAF_TYPE_OPAQUE);
139 142
	  len = a->u.ptr->length;
140 143
	}
141
      DBG("\tAttribute %02x (type %02x, %d bytes)\n", code, a->type, len);
142
      /* FIXME: Partial bit for locally added transitive attributes */
144
      DBG("\tAttribute %02x (type %02x, %d bytes, flags %02x)\n", code, a->type, len, flags);
143 145
      if (remains < len + 4)
144 146
	{
145 147
	  log(L_ERR "BGP: attribute list too long, ignoring the remaining attributes");
146 148
	  break;
147 149
	}
148
      flags = a->flags & (BAF_OPTIONAL | BAF_TRANSITIVE | BAF_PARTIAL);
149 150
      if (len < 256)
150 151
	{
151 152
	  *w++ = flags;
......
206 207
  p->bucket_node.next = NULL;
207 208
}
208 209

  
210
static int
211
bgp_compare_u32(const u32 *x, const u32 *y)
212
{
213
  return (*x < *y) ? -1 : (*x > *y) ? 1 : 0;
214
}
215

  
209 216
static void
210 217
bgp_normalize_set(u32 *dest, u32 *src, unsigned cnt)
211 218
{
212 219
  memcpy(dest, src, sizeof(u32) * cnt);
213
  /* FIXME */
220
  qsort(dest, cnt, sizeof(u32), (int(*)(const void *, const void *)) bgp_compare_u32);
214 221
}
215 222

  
216 223
static void
......
298 305
}
299 306

  
300 307
static struct bgp_bucket *
301
bgp_get_bucket(struct bgp_proto *p, ea_list *old, ea_list *tmp)
308
bgp_get_bucket(struct bgp_proto *p, ea_list *old, ea_list *tmp, int originate)
302 309
{
303 310
  ea_list *t, *new;
304 311
  unsigned i, cnt;
......
335 342
      if (EA_ID(a->id) < 32)
336 343
	seen |= 1 << EA_ID(a->id);
337 344
      *d = *a;
345
      if ((d->type & EAF_ORIGINATED) && !originate && (d->flags & BAF_TRANSITIVE) && (d->flags & BAF_OPTIONAL))
346
	d->flags |= BAF_PARTIAL;
338 347
      switch (d->type & EAF_TYPE_MASK)
339 348
	{
340
	case EAF_TYPE_INT_SET:		/* FIXME: Normalize the other attributes? */
349
	case EAF_TYPE_INT_SET:
341 350
	  {
342 351
	    struct adata *z = alloca(sizeof(struct adata) + d->u.ptr->length);
343 352
	    z->length = d->u.ptr->length;
......
402 411

  
403 412
  if (new)
404 413
    {
405
      buck = bgp_get_bucket(p, new->attrs->eattrs, tmpa);
414
      buck = bgp_get_bucket(p, new->attrs->eattrs, tmpa, new->attrs->source != RTS_BGP);
406 415
      if (!buck)			/* Inconsistent attribute list */
407 416
	return;
408 417
    }
......
682 691
	  type = desc->type;
683 692
	}
684 693
      else				/* Unknown attribute */
685
	{				/* FIXME: Send partial bit when forwarding */
694
	{
686 695
	  if (!(flags & BAF_OPTIONAL))
687 696
	    { errcode = 2; goto err; }
688 697
	  type = EAF_TYPE_OPAQUE;
......
756 765
  e = ea_find(a->eattrs, EA_CODE(EAP_BGP, BA_AS_PATH));
757 766
  ASSERT(e);
758 767
  if (bgp_path_loopy(bgp, e))
759
    return NULL;
768
    {
769
      DBG("BGP: Path loop!\n");
770
      return NULL;
771
    }
760 772

  
761 773
  /* Fill in the remaining rta fields */
762 774
  e = ea_find(a->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
......
764 776
  nexthop = *(ip_addr *) e->u.ptr->data;
765 777
  if (ipa_equal(nexthop, bgp->local_addr))
766 778
    {
767
      DBG("BGP: Loop!\n");		/* FIXME */
779
      DBG("BGP: Loop!\n");
768 780
      return NULL;
769 781
    }
770 782
  neigh = neigh_find(&bgp->p, &nexthop, 0) ? : bgp->neigh;

Also available in: Unified diff