diff options
Diffstat (limited to 'proto')
-rw-r--r-- | proto/bgp/bgp.h | 2 | ||||
-rw-r--r-- | proto/bgp/packets.c | 2 | ||||
-rw-r--r-- | proto/static/config.Y | 6 | ||||
-rw-r--r-- | proto/static/static.c | 37 | ||||
-rw-r--r-- | proto/static/static.h | 3 |
5 files changed, 32 insertions, 18 deletions
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 5d2539d5..e7647625 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -337,6 +337,8 @@ struct bgp_parse_state { u32 mp_reach_af; u32 mp_unreach_af; + mpls_label_stack mls; + uint attr_len; uint ip_reach_len; uint ip_unreach_len; diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index bee9248a..f7366804 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -753,7 +753,7 @@ bgp_apply_next_hop(struct bgp_parse_state *s, rta *a, ip_addr gw, ip_addr ll) if (ipa_zero(gw)) WITHDRAW(BAD_NEXT_HOP); - rta_set_recursive_next_hop(c->c.table, a, c->igp_table, gw, ll); + rta_set_recursive_next_hop(c->c.table, a, c->igp_table, gw, ll, &(s->mls)); } } diff --git a/proto/static/config.Y b/proto/static/config.Y index 86fcedec..cd8bfcec 100644 --- a/proto/static/config.Y +++ b/proto/static/config.Y @@ -75,8 +75,7 @@ stat_nexthop: this_snh->iface = if_get_by_name($2); } | stat_nexthop MPLS label_stack { - this_snh->label_count = $3[0]; - this_snh->label_stack = &($3[1]); + this_snh->mls = $3; } | stat_nexthop WEIGHT expr { this_snh->weight = $3 - 1; @@ -111,8 +110,7 @@ stat_route: | stat_route0 RECURSIVE ipa MPLS label_stack { this_srt->dest = RTDX_RECURSIVE; this_srt->via = $3; - this_srt->label_count = $5[0]; - this_srt->label_stack = &($5[1]); + this_srt->mls = $5; } | stat_route0 DROP { this_srt->dest = RTD_BLACKHOLE; } | stat_route0 REJECT { this_srt->dest = RTD_UNREACHABLE; } diff --git a/proto/static/static.c b/proto/static/static.c index 55fd957c..adefa0b2 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -79,8 +79,11 @@ static_announce_rte(struct static_proto *p, struct static_route *r) nh->gw = r2->via; nh->iface = r2->neigh->iface; nh->weight = r2->weight; - nh->labels = r2->label_count; - memcpy(nh->label, r2->label_stack, r2->label_count * sizeof(u32)); + if (r2->mls) + { + nh->labels = r2->mls->len; + memcpy(nh->label, r2->mls->stack, r2->mls->len * sizeof(u32)); + } nexthop_insert(&nhs, nh); } @@ -92,11 +95,7 @@ static_announce_rte(struct static_proto *p, struct static_route *r) } if (r->dest == RTDX_RECURSIVE) - { - a->nh.labels_orig = a->nh.labels = r->label_count; - memcpy(a->nh.label, r->label_stack, r->label_count * sizeof(u32)); - rta_set_recursive_next_hop(p->p.main_channel->table, a, p_igp_table(p), r->via, IPA_NONE); - } + rta_set_recursive_next_hop(p->p.main_channel->table, a, p_igp_table(p), r->via, IPA_NONE, r->mls); /* Already announced */ if (r->state == SRS_CLEAN) @@ -274,17 +273,33 @@ static_same_dest(struct static_route *x, struct static_route *y) (x->iface != y->iface) || (x->use_bfd != y->use_bfd) || (x->weight != y->weight) || - (x->label_count != y->label_count)) + (!x->mls != !y->mls) || + ((x->mls) && (y->mls) && (x->mls->len != y->mls->len))) return 0; - for (int i = 0; i < x->label_count; i++) - if (x->label_stack[i] != y->label_stack[i]) + if (!x->mls) + continue; + + for (uint i = 0; i < x->mls->len; i++) + if (x->mls->stack[i] != y->mls->stack[i]) return 0; } return !x && !y; case RTDX_RECURSIVE: - return ipa_equal(x->via, y->via); + if (!ipa_equal(x->via, y->via) || + (!x->mls != !y->mls) || + ((x->mls) && (y->mls) && (x->mls->len != y->mls->len))) + return 0; + + if (!x->mls) + return 1; + + for (uint i = 0; i < x->mls->len; i++) + if (x->mls->stack[i] != y->mls->stack[i]) + return 0; + + return 1; default: return 1; diff --git a/proto/static/static.h b/proto/static/static.h index bfcbd8c3..0976a9c9 100644 --- a/proto/static/static.h +++ b/proto/static/static.h @@ -42,9 +42,8 @@ struct static_route { byte active; /* Next hop is active (nbr/iface/BFD available) */ byte weight; /* Multipath next hop weight */ byte use_bfd; /* Configured to use BFD */ - byte label_count; /* Number of labels in stack */ struct bfd_request *bfd_req; /* BFD request, if BFD is used */ - u32 *label_stack; /* Label stack if label_count > 0 */ + mpls_label_stack *mls; /* MPLS label stack; may be NULL */ }; /* |