/* * 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"); } }
/* * 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; }