summaryrefslogtreecommitdiff
path: root/proto/bgp/packets.c
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-05-05 19:28:56 +0200
committerMaria Matejka <mq@ucw.cz>2022-05-05 19:28:56 +0200
commitf2e725a76882ba6b75c3ce4fb3c760bd83462410 (patch)
tree48883d91d8cdfaba9420efe33e1b81778e70b0a8 /proto/bgp/packets.c
parent1c30b689ddd032ef8000fb7836348a48ba3184ff (diff)
All outstanding MPLS label stacks are stored as adata
Diffstat (limited to 'proto/bgp/packets.c')
-rw-r--r--proto/bgp/packets.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index 0aa4dc40..f8228313 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -980,15 +980,18 @@ bgp_apply_next_hop(struct bgp_parse_state *s, rta *a, ip_addr gw, ip_addr ll)
s->hostentry = rt_get_hostentry(tab, gw, ll, c->c.table);
if (!s->mpls)
- rta_apply_hostentry(a, s->hostentry, NULL);
+ rta_apply_hostentry(a, s->hostentry);
/* With MPLS, hostentry is applied later in bgp_apply_mpls_labels() */
}
}
static void
-bgp_apply_mpls_labels(struct bgp_parse_state *s, rta *a, u32 *labels, uint lnum)
+bgp_apply_mpls_labels(struct bgp_parse_state *s, rta *a)
{
+ u32 *labels = (u32 *) s->mpls_labels->data;
+ u32 lnum = s->mpls_labels->length / sizeof(u32);
+
if (lnum > MPLS_MAX_LABEL_STACK)
{
REPORT("Too many MPLS labels ($u)", lnum);
@@ -1001,7 +1004,7 @@ bgp_apply_mpls_labels(struct bgp_parse_state *s, rta *a, u32 *labels, uint lnum)
/* Handle implicit NULL as empty MPLS stack */
if ((lnum == 1) && (labels[0] == BGP_MPLS_NULL))
- lnum = 0;
+ lnum = s->mpls_labels->length = 0;
if (s->channel->cf->gw_mode == GW_DIRECT)
{
@@ -1009,13 +1012,7 @@ bgp_apply_mpls_labels(struct bgp_parse_state *s, rta *a, u32 *labels, uint lnum)
memcpy(a->nh.label, labels, 4*lnum);
}
else /* GW_RECURSIVE */
- {
- mpls_label_stack ms;
-
- ms.len = lnum;
- memcpy(ms.stack, labels, 4*lnum);
- rta_apply_hostentry(a, s->hostentry, &ms);
- }
+ rta_apply_hostentry(a, s->hostentry);
}
static void
@@ -1418,7 +1415,13 @@ bgp_encode_mpls_labels(struct bgp_write_state *s UNUSED, const adata *mpls, byte
static void
bgp_decode_mpls_labels(struct bgp_parse_state *s, byte **pos, uint *len, uint *pxlen, rta *a)
{
- u32 labels[BGP_MPLS_MAX], label;
+ struct {
+ struct adata ad;
+ u32 labels[BGP_MPLS_MAX];
+ } labels_adata;
+
+ u32 *labels = labels_adata.labels;
+ u32 label;
uint lnum = 0;
do {
@@ -1440,19 +1443,19 @@ bgp_decode_mpls_labels(struct bgp_parse_state *s, byte **pos, uint *len, uint *p
if (!a)
return;
+ labels_adata.ad.length = lnum * sizeof(u32);
+
/* Attach MPLS attribute unless we already have one */
if (!s->mpls_labels)
- {
- s->mpls_labels = lp_alloc_adata(s->pool, 4*BGP_MPLS_MAX);
- bgp_set_attr_ptr(&(a->eattrs), BA_MPLS_LABEL_STACK, 0, s->mpls_labels);
- }
-
- /* Overwrite data in the attribute */
- s->mpls_labels->length = 4*lnum;
- memcpy(s->mpls_labels->data, labels, 4*lnum);
+ ea_set_attr(&(a->eattrs),
+ EA_LITERAL_DIRECT_ADATA(&ea_mpls_labels, 0,
+ (s->mpls_labels = tmp_store_adata(labels, BGP_MPLS_MAX * sizeof(u32)))));
+ else
+ /* Overwrite data in the attribute */
+ memcpy(s->mpls_labels, &labels_adata, sizeof labels_adata);
/* Update next hop entry in rta */
- bgp_apply_mpls_labels(s, a, labels, lnum);
+ bgp_apply_mpls_labels(s, a);
/* Attributes were changed, invalidate cached entry */
rta_free(s->cached_rta);