Add the ability to store link-state prefixes in the BGP table.
Store a raw copy of the BGP link state NLRI TLVs as received in the
packet in 'p.u.prefix_linkstate.ptr'.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
.description = "The BGP flowspec subsystem has detected that there was a failure for installation/removal/modification of Flowspec from the dataplane",
.suggestion = "Gather log files from the router and open an issue, Restart FRR"
},
+ {
+ .code = EC_BGP_LINKSTATE_PACKET,
+ .title = "BGP Link-State packet processing error",
+ .description = "The BGP Link-State subsystem has detected a error in the send or receive of a packet",
+ .suggestion = "Gather log files from both sides of the peering relationship and open an issue"
+ },
{
.code = EC_BGP_DOPPELGANGER_CONFIG,
.title = "BGP has detected a configuration overwrite during peer collision resolution",
EC_BGP_EVPN_INSTANCE_MISMATCH,
EC_BGP_FLOWSPEC_PACKET,
EC_BGP_FLOWSPEC_INSTALLATION,
+ EC_BGP_LINKSTATE_PACKET,
EC_BGP_ASPATH_FEWER_HOPS,
EC_BGP_DEFUNCT_SNPA_LEN,
EC_BGP_MISSING_ATTRIBUTE,
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* BGP Link-State TLV Serializer/Deserializer
+ * Copyright 2023 6WIND S.A.
+ */
+
+#include <zebra.h>
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_errors.h"
+#include "bgpd/bgp_linkstate_tlv.h"
+
+
+static uint16_t pnt_decode16(uint8_t **pnt)
+{
+ uint16_t data;
+
+ *pnt = ptr_get_be16(*pnt, &data);
+
+ return data;
+}
+
+int bgp_nlri_parse_linkstate(struct peer *peer, struct attr *attr,
+ struct bgp_nlri *packet, int withdraw)
+{
+ uint8_t *pnt;
+ uint8_t *lim;
+ afi_t afi;
+ safi_t safi;
+ uint16_t length = 0;
+ struct prefix p;
+
+ /* Start processing the NLRI - there may be multiple in the MP_REACH */
+ pnt = packet->nlri;
+ lim = pnt + packet->length;
+ afi = packet->afi;
+ safi = packet->safi;
+
+ for (; pnt < lim; pnt += length) {
+ /* Clear prefix structure. */
+ memset(&p, 0, sizeof(p));
+
+ /* All linkstate NLRI begin with NRLI type and length. */
+ if (pnt + 4 > lim)
+ return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
+
+ p.u.prefix_linkstate.nlri_type = pnt_decode16(&pnt);
+ length = pnt_decode16(&pnt);
+ /* When packet overflow occur return immediately. */
+ if (pnt + length > lim) {
+ flog_err(
+ EC_BGP_LINKSTATE_PACKET,
+ "Link-State NLRI length inconsistent (size %u seen)",
+ length);
+ return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
+ }
+ p.family = AF_LINKSTATE;
+
+ p.u.prefix_linkstate.ptr = (uintptr_t)pnt;
+ p.prefixlen = length;
+
+ /* Process the route. */
+ if (withdraw)
+ bgp_withdraw(peer, &p, 0, afi, safi, ZEBRA_ROUTE_BGP,
+ BGP_ROUTE_NORMAL, NULL, NULL, 0, NULL);
+ else
+ bgp_update(peer, &p, 0, attr, afi, safi,
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
+ NULL, 0, 0, NULL);
+ }
+ return BGP_NLRI_PARSE_OK;
+}
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* BGP Link-State TLV Serializer/Deserializer header
+ * Copyright 2023 6WIND S.A.
+ */
+
+#ifndef BGP_LINKSTATE_TLV_H
+#define BGP_LINKSTATE_TLV_H
+
+extern int bgp_nlri_parse_linkstate(struct peer *peer, struct attr *attr,
+ struct bgp_nlri *packet, int withdraw);
+
+#endif /* BGP_LINKSTATE_TLV_H */
#include "bgpd/bgp_io.h"
#include "bgpd/bgp_keepalives.h"
#include "bgpd/bgp_flowspec.h"
+#include "bgpd/bgp_linkstate_tlv.h"
#include "bgpd/bgp_trace.h"
DEFINE_HOOK(bgp_packet_dump,
return bgp_nlri_parse_evpn(peer, attr, packet, mp_withdraw);
case SAFI_FLOWSPEC:
return bgp_nlri_parse_flowspec(peer, attr, packet, mp_withdraw);
+ case SAFI_LINKSTATE:
+ return bgp_nlri_parse_linkstate(peer, attr, packet,
+ mp_withdraw);
}
+
return BGP_NLRI_PARSE_ERROR;
}
node->info = NULL;
}
+ if (family2afi(node->p.family) == AFI_LINKSTATE)
+ prefix_linkstate_ptr_free(&node->p);
+
XFREE(MTYPE_ROUTE_NODE, node);
}
bgpd/bgp_label.c \
bgpd/bgp_labelpool.c \
bgpd/bgp_lcommunity.c \
+ bgpd/bgp_linkstate_tlv.c \
bgpd/bgp_mac.c \
bgpd/bgp_memory.c \
bgpd/bgp_mpath.c \
bgpd/bgp_label.h \
bgpd/bgp_labelpool.h \
bgpd/bgp_lcommunity.h \
+ bgpd/bgp_linkstate_tlv.h \
bgpd/bgp_mac.h \
bgpd/bgp_memory.h \
bgpd/bgp_mpath.h \
const uint8_t *prefix = &p->u.prefix;
node = rn_hash_node_find(&table->hash, &search);
- if (node && node->info)
+ if (node && node->info) {
+ if (family2afi(p->family) == AFI_LINKSTATE)
+ prefix_linkstate_ptr_free(p);
+
return route_lock_node(node);
+ }
match = NULL;
node = table->top;
while (node && node->p.prefixlen <= prefixlen
&& prefix_match(&node->p, p)) {
- if (node->p.prefixlen == prefixlen)
+ if (node->p.prefixlen == prefixlen) {
+ if (family2afi(p->family) == AFI_LINKSTATE)
+ prefix_linkstate_ptr_free(p);
return route_lock_node(node);
+ }
match = node;
node = node->link[prefix_bit(prefix, node->p.prefixlen)];
table->count++;
route_lock_node(new);
+ if (family2afi(p->family) == AFI_LINKSTATE)
+ prefix_linkstate_ptr_free(p);
+
return new;
}