Beispiel #1
0
/* empty-prepend testing */
static void
empty_prepend_test (struct test_segment *t)
{
  struct aspath *asp1, *asp2, *ascratch;
  
  printf ("empty prepend %s: %s\n", t->name, t->desc);
  
  asp1 = make_aspath (t->asdata, t->len, 0);
  asp2 = aspath_empty ();
  
  ascratch = aspath_dup (asp2);
  aspath_unintern (asp2);
  
  asp2 = aspath_prepend (asp1, ascratch);
  
  printf ("aspath: %s\n", aspath_print (asp2));
  
  if (!validate (asp2, &t->sp))
    printf (OK "\n");
  else
    printf (FAILED "!\n");
  
  printf ("\n");
  aspath_unintern (asp1);
  aspath_free (asp2);
}
Beispiel #2
0
/* prepend testing */
static void
prepend_test (struct tests *t)
{
  struct aspath *asp1, *asp2, *ascratch;
  
  printf ("prepend %s: %s\n", t->test1->name, t->test1->desc);
  printf ("to %s: %s\n", t->test2->name, t->test2->desc);
  
  asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
  asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
  
  ascratch = aspath_dup (asp2);
  aspath_unintern (asp2);
  
  asp2 = aspath_prepend (asp1, ascratch);
  
  printf ("aspath: %s\n", aspath_print (asp2));
  
  if (!validate (asp2, &t->sp))
    printf ("%s\n", OK);
  else
    printf ("%s!\n", FAILED);
  
  printf ("\n");
  aspath_unintern (asp1);
  aspath_free (asp2);
}
Beispiel #3
0
static int
attr_parse (struct stream *s, u_int16_t len)
{
  u_int flag;
  u_int type;
  u_int16_t length;
  u_int16_t lim;

  lim = s->getp + len;

  printf ("attr_parse s->getp %zd, len %d, lim %d\n", s->getp, len, lim);

  while (s->getp < lim)
    {
      flag = stream_getc (s);
      type = stream_getc (s);

      if (flag & BGP_ATTR_FLAG_EXTLEN)
	length = stream_getw (s);
      else
	length = stream_getc (s);

      printf ("FLAG: %d\n", flag);
      printf ("TYPE: %d\n", type);
      printf ("Len: %d\n", length);

      switch (type)
	{
	case BGP_ATTR_ORIGIN:
	  {
	    u_char origin;
	    origin = stream_getc (s);
	    printf ("ORIGIN: %d\n", origin);
	  }
	  break;
	case BGP_ATTR_AS_PATH:
	  {
	    struct aspath *aspath;

	    aspath = aspath_parse (s, length, 1);
	    printf ("ASPATH: %s\n", aspath->str);
	    aspath_free(aspath);
	  }
	  break;
	case BGP_ATTR_NEXT_HOP:
	  {
	    struct in_addr nexthop;
	    nexthop.s_addr = stream_get_ipv4 (s);
	    printf ("NEXTHOP: %s\n", inet_ntoa (nexthop));
	  }
	  break;
	default:
	  stream_getw_from (s, length);
	  break;
	}
    }

  return 0;
}
Beispiel #4
0
static void
empty_get_test ()
{
  struct aspath *as = aspath_empty_get ();
  struct test_spec sp = { "", "", 0, 0, 0, 0, 0, 0 };

  printf ("empty_get_test, as: %s\n",aspath_print (as));
  if (!validate (as, &sp))
    printf ("%s\n", OK);
  else
    printf ("%s!\n", FAILED);
  
  printf ("\n");
  
  aspath_free (as);
}
Beispiel #5
0
/* as2+as4 reconciliation testing */
static void
as4_reconcile_test (struct tests *t)
{
  struct aspath *asp1, *asp2, *ascratch;
  
  printf ("reconciling %s:\n  %s\n", t->test1->name, t->test1->desc);
  printf ("with %s:\n  %s\n", t->test2->name, t->test2->desc);
  
  asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
  asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
  
  ascratch = aspath_reconcile_as4 (asp1, asp2);
  
  if (!validate (ascratch, &t->sp))
    printf (OK "\n");
  else
    printf (FAILED "!\n");
  
  printf ("\n");
  aspath_unintern (asp1);
  aspath_unintern (asp2);
  aspath_free (ascratch);
}
Beispiel #6
0
/* aggregation testing */
static void
aggregate_test (struct tests *t)
{
  struct aspath *asp1, *asp2, *ascratch;
  
  printf ("aggregate %s: %s\n", t->test1->name, t->test1->desc);
  printf ("with %s: %s\n", t->test2->name, t->test2->desc);
  
  asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
  asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
  
  ascratch = aspath_aggregate (asp1, asp2);
  
  if (!validate (ascratch, &t->sp))
    printf (OK "\n");
  else
    printf (FAILED "!\n");
  
  printf ("\n");
  aspath_unintern (asp1);
  aspath_unintern (asp2);
  aspath_free (ascratch);
/*  aspath_unintern (ascratch);*/
}
Beispiel #7
0
/*******************************************************************************
 函数名称  : bgp_info_mpath_aggregate_update
 功能描述  : mpath聚合路由更新
 输入参数  : 
 输出参数  : 
 返 回 值  : 无
--------------------------------------------------------------------------------
 最近一次修改记录 :
 修改作者   :      
 修改目的   :      新添加函数
 修改日期   :       2012-8-15
*******************************************************************************/
void bgp_info_mpath_aggregate_update (struct bgp_info *new_best, struct bgp_info *old_best)
{
	struct bgp_info *mpinfo;
	struct aspath *aspath;
	struct aspath *asmerge;
	struct attr *new_attr, *old_attr;
	u8 origin, attr_chg;
	struct community *community, *commerge;
	struct ecommunity *ecomm, *ecommerge;
	struct attr_extra *ae;
	struct attr attr = { 0 };
	
	if (old_best && (old_best != new_best) &&
	      (old_attr = bgp_info_mpath_attr (old_best)))
	{
		bgp_attr_unintern (&old_attr);
		bgp_info_mpath_attr_set (old_best, NULL);
	}
	
	if (!new_best)
	{
	    return;
	}
	if (!bgp_info_mpath_count (new_best))
	{
		if ((new_attr = bgp_info_mpath_attr (new_best)))
	    {
			bgp_attr_unintern (&new_attr);
			bgp_info_mpath_attr_set (new_best, NULL);
			SET_FLAG (new_best->flags, BGP_INFO_ATTR_CHANGED);
	    }
		return;
	}

	if (!CHECK_FLAG (new_best->flags, BGP_INFO_MULTIPATH_CHG) &&
				      (old_best == new_best))
	{
		attr_chg = 0;
		
		if (CHECK_FLAG (new_best->flags, BGP_INFO_ATTR_CHANGED))
		{
	        attr_chg = 1;
	    }    
		else
		{
			for (mpinfo = bgp_info_mpath_first (new_best); mpinfo;
			     mpinfo = bgp_info_mpath_next (mpinfo))
			{
				if (CHECK_FLAG (mpinfo->flags, BGP_INFO_ATTR_CHANGED))
				{
					attr_chg = 1;
					break;
				}
			}
		}	
		if (!attr_chg)
	    {
			return;
	    }
	}
	
	bgp_attr_dup (&attr, new_best->attr);
	
	/* aggregate attribute from multipath constituents */
	aspath = aspath_dup (attr.aspath);
	origin = attr.origin;
	community = attr.community ? community_dup (attr.community) : NULL;
	ae = attr.extra;
	ecomm = (ae && ae->ecommunity) ? ecommunity_dup (ae->ecommunity) : NULL;
	
	for (mpinfo = bgp_info_mpath_first (new_best); mpinfo;
		       mpinfo = bgp_info_mpath_next (mpinfo))
	{
		asmerge = aspath_aggregate (aspath, mpinfo->attr->aspath);
		aspath_free (aspath);
		aspath = asmerge;
		
		if (origin < mpinfo->attr->origin)
		{
	        origin = mpinfo->attr->origin;
		}
		if (mpinfo->attr->community)
	    {
			if (community)
	        {
				commerge = community_merge (community, mpinfo->attr->community);
				community = community_uniq_sort (commerge);
				community_free (&commerge);
	        }
			else
			{
				community = community_dup (mpinfo->attr->community);
			}
	    }
	    
		ae = mpinfo->attr->extra;
		if (ae && ae->ecommunity)
	    {
			if (ecomm)
			{
				ecommerge = ecommunity_merge (ecomm, ae->ecommunity);
				ecomm = ecommunity_uniq_sort (ecommerge);
				ecommunity_free (ecommerge);
			}
			else
			{
	            ecomm = ecommunity_dup (ae->ecommunity);
            }
	    }
	}

	attr.aspath = aspath;
	attr.origin = origin;
	if (community)
	{
		attr.community = community;
		attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
	}
	if (ecomm)
	{
		ae = bgp_attr_extra_get (&attr);
		ae->ecommunity = ecomm;
		attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
	}

	/* Zap multipath attr nexthop so we set nexthop to self */
	attr.nexthop.s_addr = 0;
#ifdef HAVE_IPV6
	if (attr.extra)
	{
	    memset (&attr.extra->mp_nexthop_global, 0, sizeof (struct in6_addr));
    }
#endif /* HAVE_IPV6 */

	new_attr = bgp_attr_intern (&attr);
	bgp_attr_extra_free (&attr);
	
	if (new_attr != bgp_info_mpath_attr (new_best))
	{
		if ((old_attr = bgp_info_mpath_attr (new_best)))
		{
			bgp_attr_unintern (&old_attr);
		}
		bgp_info_mpath_attr_set (new_best, new_attr);
		SET_FLAG (new_best->flags, BGP_INFO_ATTR_CHANGED);
	}
	else
	{
	    bgp_attr_unintern (&new_attr);
    }
}
Beispiel #8
0
/* validate the given aspath */
static int
validate (struct aspath *as, const struct test_spec *sp)
{
  size_t bytes, bytes4;
  int fails = 0;
  const u_char *out;
  static struct stream *s;
  struct aspath *asinout, *asconfeddel, *asstr, *as4;
  
  out = aspath_snmp_pathseg (as, &bytes);
  asinout = make_aspath (out, bytes, 0);
  
  /* Excercise AS4 parsing a bit, with a dogfood test */
  if (!s)
    s = stream_new (4096);
  bytes4 = aspath_put (s, as, 1);
  as4 = make_aspath (STREAM_DATA(s), bytes4, 1);
  
  asstr = aspath_str2aspath (sp->shouldbe);
  
  asconfeddel = aspath_delete_confed_seq (aspath_dup (asinout));
  
  printf ("got: %s\n", aspath_print(as));
  
  /* the parsed path should match the specified 'shouldbe' string.
   * We should pass the "eat our own dog food" test, be able to output
   * this path and then input it again. Ie the path resulting from:
   *
   *   aspath_parse(aspath_put(as)) 
   *
   * should:
   *
   * - also match the specified 'shouldbe' value
   * - hash to same value as original path
   * - have same hops and confed counts as original, and as the
   *   the specified counts
   *
   * aspath_str2aspath() and shouldbe should match
   *
   * We do the same for:
   *
   *   aspath_parse(aspath_put(as,USE32BIT))
   *
   * Confederation related tests: 
   * - aspath_delete_confed_seq(aspath) should match shouldbe_confed
   * - aspath_delete_confed_seq should be idempotent.
   */
  if (strcmp(aspath_print (as), sp->shouldbe)
         /* hash validation */
      || (aspath_key_make (as) != aspath_key_make (asinout))
         /* by string */
      || strcmp(aspath_print (asinout), sp->shouldbe)
         /* By 4-byte parsing */
      || strcmp(aspath_print (as4), sp->shouldbe)
         /* by various path counts */
      || (aspath_count_hops (as) != sp->hops)
      || (aspath_count_confeds (as) != sp->confeds)
      || (aspath_count_hops (asinout) != sp->hops)
      || (aspath_count_confeds (asinout) != sp->confeds))
    {
      failed++;
      fails++;
      printf ("shouldbe:\n%s\n", sp->shouldbe);
      printf ("as4:\n%s\n", aspath_print (as4));
      printf ("hash keys: in: %d out->in: %d\n", 
              aspath_key_make (as), aspath_key_make (asinout));
      printf ("hops: %d, counted %d %d\n", sp->hops, 
              aspath_count_hops (as),
              aspath_count_hops (asinout) );
      printf ("confeds: %d, counted %d %d\n", sp->confeds,
              aspath_count_confeds (as),
              aspath_count_confeds (asinout));
      printf ("out->in:\n%s\nbytes: ", aspath_print(asinout));
      printbytes (out, bytes);
    }
         /* basic confed related tests */
  if ((aspath_print (asconfeddel) == NULL 
          && sp->shouldbe_delete_confed != NULL)
      || (aspath_print (asconfeddel) != NULL 
          && sp->shouldbe_delete_confed == NULL)
      || strcmp(aspath_print (asconfeddel), sp->shouldbe_delete_confed)
         /* delete_confed_seq should be idempotent */
      || (aspath_key_make (asconfeddel) 
          != aspath_key_make (aspath_delete_confed_seq (asconfeddel))))
    {
      failed++;
      fails++;
      printf ("confed_del: %s\n", aspath_print (asconfeddel));
      printf ("should be: %s\n", sp->shouldbe_delete_confed);
    }
      /* aspath_str2aspath test */
  if ((aspath_print (asstr) == NULL && sp->shouldbe != NULL)
      || (aspath_print (asstr) != NULL && sp->shouldbe == NULL)
      || strcmp(aspath_print (asstr), sp->shouldbe))
    {
      failed++;
      fails++;
      printf ("asstr: %s\n", aspath_print (asstr));
    }
  
    /* loop, private and first as checks */
  if ((sp->does_loop && aspath_loop_check (as, sp->does_loop) == 0)
      || (sp->doesnt_loop && aspath_loop_check (as, sp->doesnt_loop) != 0)
      || (aspath_private_as_check (as) != sp->private_as)
      || (aspath_firstas_check (as,sp->first)
          && sp->first == 0))
    {
      failed++;
      fails++;
      printf ("firstas: %d,  got %d\n", sp->first,
              aspath_firstas_check (as,sp->first));
      printf ("loop does: %d %d, doesnt: %d %d\n",
              sp->does_loop, aspath_loop_check (as, sp->does_loop),
              sp->doesnt_loop, aspath_loop_check (as, sp->doesnt_loop));
      printf ("private check: %d %d\n", sp->private_as,
              aspath_private_as_check (as));
    }
  aspath_unintern (asinout);
  aspath_unintern (as4);
  
  aspath_free (asconfeddel);
  aspath_free (asstr);
  stream_reset (s);
  
  return fails;
}