if (!r2->active)
continue;
- struct nexthop *nh = allocz(NEXTHOP_MAX_SIZE);
- nh->gw = r2->via;
- nh->iface = r2->neigh->iface;
- nh->flags = r2->onlink ? RNF_ONLINK : 0;
- nh->weight = r2->weight;
+ *nh = (struct nexthop) {
+ .gw = r2->via,
+ .iface = r2->neigh->iface,
+ .flags = r2->onlink ? RNF_ONLINK : 0,
+ .weight = r2->weight,
+ };
+
if (r2->mls)
{
- nh->labels = r2->mls->len;
- memcpy(nh->label, r2->mls->stack, r2->mls->len * sizeof(u32));
+ nh->labels = r2->mls->length / sizeof(u32);
+ memcpy(nh->label, r2->mls->data, r2->mls->length);
}
- nexthop_insert(&nhs, nh);
+ nh = NEXTHOP_NEXT(nh);
}
- if (!nhs)
- goto withdraw;
-
- nexthop_link(a, nhs);
+ ea_set_attr_data(&ea, &ea_gen_nexthop, 0,
+ nhad->ad.data, (void *) nh - (void *) nhad->ad.data);
}
- if (r->dest == RTDX_RECURSIVE)
+ else if (r->dest == RTDX_RECURSIVE)
{
rtable *tab = ipa_is_ip4(r->via) ? p->igp_table_ip4 : p->igp_table_ip6;
- rta_set_recursive_next_hop(p->p.main_channel->table, a, tab, r->via, IPA_NONE, r->mls);
+ u32 *labels = r->mls ? (void *) r->mls->data : NULL;
+ u32 lnum = r->mls ? r->mls->length / sizeof(u32) : 0;
+
+ ea_set_hostentry(&ea, p->p.main_channel->table, tab,
+ r->via, IPA_NONE, lnum, labels);
++
}
- ea_list *ea = alloca(sizeof(ea_list) + 2 * sizeof(eattr));
- *ea = (ea_list) { .flags = EALF_SORTED };
- ea->next = a->eattrs;
- a->eattrs = ea;
-
+ else if (r->dest)
+ ea_set_dest(&ea, 0, r->dest);
+
+ if (p->p.mpls_channel)
+ {
+ struct mpls_channel *mc = (void *) p->p.mpls_channel;
+
- ea->attrs[0] = (eattr) {
- .id = EA_MPLS_LABEL,
- .type = EAF_TYPE_INT,
- .u.data = r->mpls_label,
- };
-
- ea->attrs[1] = (eattr) {
- .id = EA_MPLS_POLICY,
- .type = EAF_TYPE_INT,
- .u.data = MPLS_POLICY_STATIC,
- };
-
- ea->count = 2;
+ if (r->mpls_label != (uint) -1)
+ {
- ea->attrs[0] = (eattr) {
- .id = EA_MPLS_POLICY,
- .type = EAF_TYPE_INT,
- .u.data = mc->label_policy,
- };
-
- ea->count = 1;
++ ea_set_attr_u32(&ea, &ea_gen_mpls_label, 0, r->mpls_label);
++ ea_set_attr_u32(&ea, &ea_gen_mpls_policy, 0, MPLS_POLICY_STATIC);
+ }
+ else
+ {
++ ea_set_attr_u32(&ea, &ea_gen_mpls_policy, 0, mc->label_policy);
+ }
+ }
+
/* Already announced */
if (r->state == SRS_CLEAN)
return;
if (!cf->igp_table_ip6)
cf->igp_table_ip6 = (cc->table->addr_type == NET_IP6) ?
- cc->table : cf->c.global->def_tables[NET_IP6];
+ cc->table : rt_get_default_table(cf->c.global, NET_IP6);
WALK_LIST(r, cf->routes)
+ {
if (r->net && (r->net->type != CF->net_type))
cf_error("Route %N incompatible with channel type", r->net);