summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
authorJan Moskyto Matejka <mq@ucw.cz>2017-03-17 15:48:09 +0100
committerJan Moskyto Matejka <mq@ucw.cz>2017-03-17 15:48:32 +0100
commit3c74416465d77c0e79eeaaeb988e471663484b5d (patch)
tree44f84dccd613fd36700729972d9329369275d785 /proto
parenta5d2a34497853a02692a0b8ea812f44d6820a399 (diff)
Nexthop: Fixed recursive route mpls label merging
Diffstat (limited to 'proto')
-rw-r--r--proto/bgp/bgp.h2
-rw-r--r--proto/bgp/packets.c2
-rw-r--r--proto/static/config.Y6
-rw-r--r--proto/static/static.c37
-rw-r--r--proto/static/static.h3
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 */
};
/*