Exemple #1
0
void
check_replace(struct route_node *np2, struct rib *rib2, 
              struct route_node **np, struct rib **rib)
{
  int proto, proto2;

  if (!*np)
    {
      *np = np2;
      *rib = rib2;
      return;
    }

  if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) < 0)
    return;
  if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) > 0)
    {
      *np = np2;
      *rib = rib2;
      return;
    }

  proto = proto_trans((*rib)->type);
  proto2 = proto_trans(rib2->type);

  if (proto2 > proto)
    return;
  if (proto2 < proto)
    {
      *np = np2;
      *rib = rib2;
      return;
    }

#if 0
  if (in_addr_cmp((u_char *)&(*rib)->u.gate4, (u_char *)&rib2->u.gate4) <= 0)
    return;
#endif /* 0 */

  *np = np2;
  *rib = rib2;
  return;
}
void
get_fwtable_route_node(struct variable *v, oid objid[], size_t *objid_len, 
		       int exact, struct route_node **np, struct rib **rib)
{
  struct in_addr dest;
  struct route_table *table;
  struct route_node *np2;
  struct rib *rib2;
  int proto;
  int policy;
  struct in_addr nexthop;
  u_char *pnt;
  int i;

  /* Init index variables */

  pnt = (u_char *) &dest;
  for (i = 0; i < 4; i++)
    *pnt++ = 0;

  pnt = (u_char *) &nexthop;
  for (i = 0; i < 4; i++)
    *pnt++ = 0;

  proto = 0;
  policy = 0;
 
  /* Init return variables */

  *np = NULL;
  *rib = NULL;

  /* Short circuit exact matches of wrong length */

  if (exact && (*objid_len != (unsigned) v->namelen + 10))
    return;

  table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  if (! table)
    return;

  /* Get INDEX information out of OID.
   * ipForwardDest, ipForwardProto, ipForwardPolicy, ipForwardNextHop
   */

  if (*objid_len > v->namelen)
    oid2in_addr (objid + v->namelen, MIN(4, *objid_len - v->namelen), &dest);

  if (*objid_len > (unsigned) v->namelen + 4)
    proto = objid[v->namelen + 4];

  if (*objid_len > (unsigned) v->namelen + 5)
    policy = objid[v->namelen + 5];

  if (*objid_len > (unsigned) v->namelen + 6)
    oid2in_addr (objid + v->namelen + 6, MIN(4, *objid_len - v->namelen - 6),
		 &nexthop);

  /* Apply GETNEXT on not exact search */

  if (!exact && (*objid_len >= (unsigned) v->namelen + 10))
    {
      if (! in_addr_add((u_char *) &nexthop, 1)) 
        return;
    }

  /* For exact: search matching entry in rib table. */

  if (exact)
    {
      if (policy) /* Not supported (yet?) */
        return;
      for (*np = route_top (table); *np; *np = route_next (*np))
	{
	  if (!in_addr_cmp(&(*np)->p.u.prefix, (u_char *)&dest))
	    {
	      for (*rib = (*np)->info; *rib; *rib = (*rib)->next)
	        {
		  if (!in_addr_cmp((u_char *)&(*rib)->nexthop->gate.ipv4,
				   (u_char *)&nexthop))
		    if (proto == proto_trans((*rib)->type))
		      return;
		}
	    }
	}
      return;
    }

  /* Search next best entry */

  for (np2 = route_top (table); np2; np2 = route_next (np2))
    {

      /* Check destination first */
      if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) > 0)
        for (rib2 = np2->info; rib2; rib2 = rib2->next)
	  check_replace(np2, rib2, np, rib);

      if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) == 0)
        { /* have to look at each rib individually */
          for (rib2 = np2->info; rib2; rib2 = rib2->next)
	    {
	      int proto2, policy2;

	      proto2 = proto_trans(rib2->type);
	      policy2 = 0;

	      if ((policy < policy2)
		  || ((policy == policy2) && (proto < proto2))
		  || ((policy == policy2) && (proto == proto2)
		      && (in_addr_cmp((u_char *)&rib2->nexthop->gate.ipv4,
				      (u_char *) &nexthop) >= 0)
		      ))
		check_replace(np2, rib2, np, rib);
	    }
	}
    }

  if (!*rib)
    return;

  policy = 0;
  proto = proto_trans((*rib)->type);

  *objid_len = v->namelen + 10;
  pnt = (u_char *) &(*np)->p.u.prefix;
  for (i = 0; i < 4; i++)
    objid[v->namelen + i] = *pnt++;

  objid[v->namelen + 4] = proto;
  objid[v->namelen + 5] = policy;

  {
    struct nexthop *nexthop;

    nexthop = (*rib)->nexthop;
    if (nexthop)
      {
	pnt = (u_char *) &nexthop->gate.ipv4;
	for (i = 0; i < 4; i++)
	  objid[i + v->namelen + 6] = *pnt++;
      }
  }

  return;
}