示例#1
0
/*
 * zfpm_dt_log_fpm_message
 */
static void zfpm_dt_log_fpm_message(Fpm__Message *msg)
{
	Fpm__AddRoute *add_route;
	Fpm__Nexthop *nexthop;
	struct prefix prefix;
	uint8_t family, nh_family;
	uint if_index;
	char *if_name;
	size_t i;
	char buf[INET6_ADDRSTRLEN];
	union g_addr nh_addr;

	if (msg->type != FPM__MESSAGE__TYPE__ADD_ROUTE)
		return;

	zfpm_debug("Add route message");
	add_route = msg->add_route;

	if (!qpb_address_family_get(add_route->address_family, &family))
		return;

	if (!qpb_l3_prefix_get(add_route->key->prefix, family, &prefix))
		return;

	zfpm_debug("Vrf id: %d, Prefix: %s/%d, Metric: %d", add_route->vrf_id,
		   inet_ntop(family, &prefix.u.prefix, buf, sizeof(buf)),
		   prefix.prefixlen, add_route->metric);

	/*
	 * Go over nexthops.
	 */
	for (i = 0; i < add_route->n_nexthops; i++) {
		nexthop = add_route->nexthops[i];
		if (!qpb_if_identifier_get(nexthop->if_id, &if_index, &if_name))
			continue;

		if (nexthop->address)
			qpb_l3_address_get(nexthop->address, &nh_family,
					   &nh_addr);

		zfpm_debug("Nexthop - if_index: %d (%s), gateway: %s, ",
			   if_index, if_name ? if_name : "name not specified",
			   nexthop->address ? inet_ntoa(nh_addr.ipv4) : "None");
	}
}
示例#2
0
/*
 * create_add_route_message
 */
static Fpm__AddRoute *create_add_route_message(qpb_allocator_t *allocator,
					       rib_dest_t *dest,
					       struct route_entry *re)
{
	Fpm__AddRoute *msg;
	struct nexthop *nexthop;
	uint num_nhs, u;
	struct nexthop *nexthops[MULTIPATH_NUM];

	msg = QPB_ALLOC(allocator, typeof(*msg));
	if (!msg) {
		assert(0);
		return NULL;
	}

	fpm__add_route__init(msg);

	msg->vrf_id = zvrf_id(rib_dest_vrf(dest));

	qpb_address_family_set(&msg->address_family, rib_dest_af(dest));

	/*
	 * XXX Hardcode subaddress family for now.
	 */
	msg->sub_address_family = QPB__SUB_ADDRESS_FAMILY__UNICAST;
	msg->key = fpm_route_key_create(allocator, rib_dest_prefix(dest));
	qpb_protocol_set(&msg->protocol, re->type);
	msg->has_route_type = 1;
	msg->route_type = FPM__ROUTE_TYPE__NORMAL;
	msg->metric = re->metric;

	/*
	 * Figure out the set of nexthops to be added to the message.
	 */
	num_nhs = 0;
	for (ALL_NEXTHOPS(re->ng, nexthop)) {
		if (num_nhs >= multipath_num)
			break;

		if (num_nhs >= ZEBRA_NUM_OF(nexthops))
			break;

		if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) {
			switch (nexthop->bh_type) {
			case BLACKHOLE_REJECT:
				msg->route_type = FPM__ROUTE_TYPE__UNREACHABLE;
				break;
			case BLACKHOLE_NULL:
			default:
				msg->route_type = FPM__ROUTE_TYPE__BLACKHOLE;
				break;
			}
			return msg;
		}

		if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
			continue;

		if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
			continue;

		nexthops[num_nhs] = nexthop;
		num_nhs++;
	}

	if (!num_nhs) {
		zfpm_debug("netlink_encode_route(): No useful nexthop.");
		assert(0);
		return NULL;
	}

	/*
	 * And add them to the message.
	 */
	if (!(msg->nexthops = qpb_alloc_ptr_array(allocator, num_nhs))) {
		assert(0);
		return NULL;
	}

	msg->n_nexthops = 0;
	for (u = 0; u < num_nhs; u++) {
		if (!add_nexthop(allocator, msg, dest, nexthops[u])) {
			assert(0);
			return NULL;
		}
	}

	assert(msg->n_nexthops == num_nhs);

	return msg;
}
/*
 * create_add_route_message
 */
static Fpm__AddRoute *
create_add_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
			  struct rib *rib)
{
  Fpm__AddRoute *msg;
  int discard;
  struct nexthop *nexthop, *tnexthop;
  int recursing;
  uint num_nhs, u;
  struct nexthop *nexthops[MAX (MULTIPATH_NUM, 64)];

  msg = QPB_ALLOC(allocator, typeof(*msg));
  if (!msg) {
    assert(0);
    return NULL;
  }

  fpm__add_route__init(msg);

  msg->vrf_id = rib_dest_vrf(dest)->vrf_id;

  qpb_address_family_set (&msg->address_family, rib_dest_af(dest));

  /*
   * XXX Hardcode subaddress family for now.
   */
  msg->sub_address_family = QPB__SUB_ADDRESS_FAMILY__UNICAST;
  msg->key = fpm_route_key_create (allocator, rib_dest_prefix(dest));
  qpb_protocol_set (&msg->protocol, rib->type);

  if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT))
    discard = 1;
  else
    discard = 0;

  if (discard)
    {
      if (rib->flags & ZEBRA_FLAG_BLACKHOLE) {
	msg->route_type = FPM__ROUTE_TYPE__BLACKHOLE;
      } else if (rib->flags & ZEBRA_FLAG_REJECT) {
	msg->route_type = FPM__ROUTE_TYPE__UNREACHABLE;
      } else {
	assert (0);
      }
      return msg;
    }
  else {
    msg->route_type = FPM__ROUTE_TYPE__NORMAL;
  }

  msg->metric = rib->metric;

  /*
   * Figure out the set of nexthops to be added to the message.
   */
  num_nhs = 0;
  for (ALL_NEXTHOPS_RO (rib->nexthop, nexthop, tnexthop, recursing))
    {
      if (MULTIPATH_NUM != 0 && num_nhs >= MULTIPATH_NUM)
        break;

      if (num_nhs >= ZEBRA_NUM_OF(nexthops))
	break;

      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
        continue;

      if (!CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
	continue;

      nexthops[num_nhs] = nexthop;
      num_nhs++;
    }

  if (!num_nhs) {
    zfpm_debug ("netlink_encode_route(): No useful nexthop.");
    assert(0);
    return NULL;
  }

  /*
   * And add them to the message.
   */
  if (!(msg->nexthops = qpb_alloc_ptr_array(allocator, num_nhs))) {
    assert(0);
    return NULL;
  }

  msg->n_nexthops = 0;
  for (u = 0; u < num_nhs; u++) {
    if (!add_nexthop(allocator, msg, dest, nexthops[u])) {
      assert(0);
      return NULL;
    }
  }

  assert(msg->n_nexthops == num_nhs);

  return msg;
}