summaryrefslogtreecommitdiffstats
path: root/fpm
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--fpm/fpm.proto145
-rw-r--r--fpm/fpm_pb.c5
-rw-r--r--fpm/fpm_pb.h400
3 files changed, 550 insertions, 0 deletions
diff --git a/fpm/fpm.proto b/fpm/fpm.proto
index 9f0917f..beaa5d6 100644
--- a/fpm/fpm.proto
+++ b/fpm/fpm.proto
@@ -6,6 +6,9 @@
//
// @author Avneesh Sachdev <avneesh@sproute.com>
//
+// Portions:
+// Copyright (C) 2024 Carmine Scarpitta (for SRv6)
+//
// Permission to use, copy, modify, and/or distribute this software
// for any purpose with or without fee is hereby granted, provided
// that the above copyright notice and this permission notice appear
@@ -72,6 +75,141 @@ message AddRoute {
required int32 metric = 8;
repeated Nexthop nexthops = 9;
+
+ /* Source Address of outer encapsulating IPv6 header */
+ optional qpb.Ipv6Address srv6_encap_source_address = 10;
+ /* SRv6 SID for VPN use cases */
+ optional qpb.Ipv6Address srv6_vpn_sid = 11;
+}
+
+/* SID Format - as per RFC 8986 section #3.1 */
+message SRv6SIDFormat
+{
+ /* Locator block length */
+ required uint32 locator_block_length = 1;
+ /* Locator node length */
+ required uint32 locator_node_length = 2;
+ /* Function length */
+ required uint32 function_length = 3;
+ /* Argument length */
+ required uint32 argument_length = 4;
+}
+
+/* SRv6 Local SID */
+message SRv6LocalSID
+{
+ /* SRv6 SID value */
+ required qpb.Ipv6Address sid = 1;
+
+ /* SID Format - as per RFC 8986 section #3.1 */
+ optional SRv6SIDFormat sid_format = 2;
+
+ /* SRv6 Endpoint Behavior associated with the SID */
+ oneof end_behavior
+ {
+ /* Endpoint */
+ End end = 3;
+ /* Endpoint with L3 cross-connect */
+ EndX end_x = 4;
+ /* Endpoint with specific IPv6 table lookup */
+ EndT end_t = 5;
+ /* Endpoint with decapsulation and IPv6 cross-connect */
+ EndDX6 end_dx6 = 7;
+ /* Endpoint with decapsulation and IPv4 cross-connect */
+ EndDX4 end_dx4 = 8;
+ /* Endpoint with decapsulation and specific IPv6 table lookup */
+ EndDT6 end_dt6 = 9;
+ /* Endpoint with decapsulation and specific IPv4 table lookup */
+ EndDT4 end_dt4 = 10;
+ /* Endpoint with decapsulation and specific IP table lookup */
+ EndDT46 end_dt46 = 11;
+ /* Endpoint behavior with NEXT-CSID, PSP and USD flavors */
+ UN un = 12;
+ /* End.X behavior with NEXT-CSID, PSP and USD flavors */
+ UA ua = 13;
+ /* End.DT6 behavior with NEXT-CSID flavor */
+ UDT6 udt6 = 14;
+ /* End.DT4 behavior with NEXT-CSID flavor */
+ UDT4 udt4 = 15;
+ /* End.DT46 behavior with NEXT-CSID flavor */
+ UDT46 udt46 = 16;
+ }
+
+ /* Endpoint */
+ message End
+ {
+ }
+
+ /* Endpoint with L3 cross-connect */
+ message EndX
+ {
+ required Nexthop nexthop = 1;
+ }
+
+ /* Endpoint with specific IPv6 table lookup */
+ message EndT
+ {
+ required uint32 vrf_id = 1;
+ }
+
+ /* Endpoint with decapsulation and IPv6 cross-connect */
+ message EndDX6
+ {
+ required Nexthop nexthop = 1;
+ }
+
+ /* Endpoint with decapsulation and IPv4 cross-connect */
+ message EndDX4
+ {
+ required Nexthop nexthop = 1;
+ }
+
+ /* Endpoint with decapsulation and specific IPv6 table lookup */
+ message EndDT6
+ {
+ required uint32 vrf_id = 1;
+ }
+
+ /* Endpoint with decapsulation and specific IPv4 table lookup */
+ message EndDT4
+ {
+ required uint32 vrf_id = 1;
+ }
+
+ /* Endpoint with decapsulation and specific IP table lookup */
+ message EndDT46
+ {
+ required uint32 vrf_id = 1;
+ }
+
+ /* Endpoint behavior with NEXT-CSID, PSP and USD flavors */
+ message UN
+ {
+ }
+
+ /* End.X behavior with NEXT-CSID, PSP and USD flavors */
+ message UA
+ {
+ required Nexthop nexthop = 1;
+ }
+
+ /* End.DT6 behavior with NEXT-CSID flavor */
+ message UDT6
+ {
+ required uint32 vrf_id = 1;
+ }
+
+ /* End.DT4 behavior with NEXT-CSID flavor */
+ message UDT4
+ {
+ required uint32 vrf_id = 1;
+ }
+
+ /* End.DT46 behavior with NEXT-CSID flavor */
+ message UDT46
+ {
+ required uint32 vrf_id = 1;
+ }
}
//
@@ -82,10 +220,17 @@ message Message {
UNKNOWN_MSG = 0;
ADD_ROUTE = 1;
DELETE_ROUTE = 2;
+ /* Install an SRv6 Local SID */
+ ADD_SRV6_LOCALSID = 3;
+ /* Remove an SRv6 Local SID */
+ DELETE_SRV6_LOCALSID = 4;
};
optional Type type = 1;
optional AddRoute add_route = 2;
optional DeleteRoute delete_route = 3;
+
+ /* SRv6 Local SID */
+ optional SRv6LocalSID srv6_localsid = 4;
}
diff --git a/fpm/fpm_pb.c b/fpm/fpm_pb.c
index e4c9395..0e8f618 100644
--- a/fpm/fpm_pb.c
+++ b/fpm/fpm_pb.c
@@ -10,3 +10,8 @@
/*
* Main file for the fpm_pb library.
*/
+
+#include "config.h"
+#include "xref.h"
+
+XREF_SETUP();
diff --git a/fpm/fpm_pb.h b/fpm/fpm_pb.h
index 7e39054..23d7e43 100644
--- a/fpm/fpm_pb.h
+++ b/fpm/fpm_pb.h
@@ -5,6 +5,9 @@
* @copyright Copyright (C) 2016 Sproute Networks, Inc.
*
* @author Avneesh Sachdev <avneesh@sproute.com>
+ *
+ * Portions:
+ * Copyright (C) 2024 Carmine Scarpitta (for SRv6)
*/
/*
@@ -15,6 +18,7 @@
#define _FPM_PB_H
#include "lib/route_types.h"
+#include "lib/vrf.h"
#include "qpb/qpb.h"
#include "fpm/fpm.pb-c.h"
@@ -42,4 +46,400 @@ static inline Fpm__RouteKey *fpm__route_key__create(qpb_allocator_t *allocator,
return key;
}
+/*
+ * fpm__nexthop__create
+ */
+#define fpm_nexthop_create fpm__nexthop__create
+static inline Fpm__Nexthop *
+fpm__nexthop__create(qpb_allocator_t *allocator, struct nexthop *nh)
+{
+ Fpm__Nexthop *nexthop;
+ uint8_t family;
+
+ nexthop = QPB_ALLOC(allocator, typeof(*nexthop));
+ if (!nexthop)
+ return NULL;
+
+ fpm__nexthop__init(nexthop);
+
+ if (nh->type == NEXTHOP_TYPE_IPV4 ||
+ nh->type == NEXTHOP_TYPE_IPV4_IFINDEX)
+ family = AF_INET;
+ else if (nh->type == NEXTHOP_TYPE_IPV6 ||
+ nh->type == NEXTHOP_TYPE_IPV6_IFINDEX)
+ family = AF_INET6;
+ else
+ return NULL;
+
+ nexthop->if_id = qpb__if_identifier__create(allocator, nh->ifindex);
+ if (!nexthop->if_id)
+ return NULL;
+
+ nexthop->address = qpb__l3_address__create(allocator, &nh->gate, family);
+ if (!nexthop->address)
+ return NULL;
+
+
+ return nexthop;
+}
+
+/*
+ * fpm__nexthop__get
+ *
+ * Read out information from a protobuf nexthop structure.
+ */
+#define fpm_nexthop_get fpm__nexthop__get
+static inline int fpm__nexthop__get(const Fpm__Nexthop *nh,
+ struct nexthop *nexthop)
+{
+ struct in_addr ipv4;
+ struct in6_addr ipv6;
+ uint32_t ifindex;
+ char *ifname;
+
+ if (!nh)
+ return 0;
+
+ if (!qpb_if_identifier_get(nh->if_id, &ifindex, &ifname))
+ return 0;
+
+ if (nh->address) {
+ if (nh->address->v4) {
+ memset(&ipv4, 0, sizeof(ipv4));
+ if (!qpb__ipv4_address__get(nh->address->v4, &ipv4))
+ return 0;
+
+ nexthop->vrf_id = VRF_DEFAULT;
+ nexthop->type = NEXTHOP_TYPE_IPV4;
+ nexthop->gate.ipv4 = ipv4;
+ if (ifindex) {
+ nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
+ nexthop->ifindex = ifindex;
+ }
+ return 1;
+ }
+
+ if (nh->address->v6) {
+ memset(&ipv6, 0, sizeof(ipv6));
+ if (!qpb__ipv6_address__get(nh->address->v6, &ipv6))
+ return 0;
+ nexthop->vrf_id = VRF_DEFAULT;
+ nexthop->type = NEXTHOP_TYPE_IPV6;
+ nexthop->gate.ipv6 = ipv6;
+ if (ifindex) {
+ nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
+ nexthop->ifindex = ifindex;
+ }
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * fpm__srv6_sid_format__create
+ */
+#define fpm_srv6_sid_format_create fpm__srv6_sid_format__create
+static inline Fpm__SRv6SIDFormat *
+fpm__srv6_sid_format__create(qpb_allocator_t *allocator,
+ uint8_t locator_block_length,
+ uint8_t locator_node_length,
+ uint8_t function_length, uint8_t argument_length)
+{
+ Fpm__SRv6SIDFormat *sid_format;
+
+ sid_format = QPB_ALLOC(allocator, typeof(*sid_format));
+ if (!sid_format)
+ return NULL;
+ fpm__srv6_sidformat__init(sid_format);
+
+ sid_format->locator_block_length = locator_block_length;
+ sid_format->locator_node_length = locator_node_length;
+ sid_format->function_length = function_length;
+ sid_format->argument_length = argument_length;
+
+ return sid_format;
+}
+
+/*
+ * fpm__srv6_local_sid_end_behavior__create
+ */
+#define fpm_srv6_local_sid_end_behavior_create \
+ fpm__srv6_local_sid_end_behavior__create
+static inline Fpm__SRv6LocalSID__End *
+fpm__srv6_local_sid_end_behavior__create(qpb_allocator_t *allocator)
+{
+ Fpm__SRv6LocalSID__End *end;
+
+ end = QPB_ALLOC(allocator, typeof(*end));
+ if (!end)
+ return NULL;
+
+ fpm__srv6_local_sid__end__init(end);
+
+ return end;
+}
+
+/*
+ * fpm__srv6_local_sid_end_x_behavior__create
+ */
+#define fpm_srv6_local_sid_end_x_behavior_create \
+ fpm__srv6_local_sid_end_x_behavior__create
+static inline Fpm__SRv6LocalSID__EndX *
+fpm__srv6_local_sid_end_x_behavior__create(qpb_allocator_t *allocator,
+ struct nexthop *nexthop)
+{
+ Fpm__SRv6LocalSID__EndX *end_x;
+
+ end_x = QPB_ALLOC(allocator, typeof(*end_x));
+ if (!end_x)
+ return NULL;
+
+ fpm__srv6_local_sid__end_x__init(end_x);
+
+ end_x->nexthop = fpm_nexthop_create(allocator, nexthop);
+
+ return end_x;
+}
+
+/*
+ * fpm__srv6_local_sid_end_t_behavior__create
+ */
+#define fpm_srv6_local_sid_end_t_behavior_create \
+ fpm__srv6_local_sid_end_t_behavior__create
+static inline Fpm__SRv6LocalSID__EndT *
+fpm__srv6_local_sid_end_t_behavior__create(qpb_allocator_t *allocator,
+ vrf_id_t vrf_id)
+{
+ Fpm__SRv6LocalSID__EndT *end_t;
+
+ end_t = QPB_ALLOC(allocator, typeof(*end_t));
+ if (!end_t)
+ return NULL;
+
+ fpm__srv6_local_sid__end_t__init(end_t);
+
+ end_t->vrf_id = vrf_id;
+
+ return end_t;
+}
+
+/*
+ * fpm__srv6_local_sid_end_dx6_behavior__create
+ */
+#define fpm_srv6_local_sid_end_dx6_behavior_create \
+ fpm__srv6_local_sid_end_dx6_behavior__create
+static inline Fpm__SRv6LocalSID__EndDX6 *
+fpm__srv6_local_sid_end_dx6_behavior__create(qpb_allocator_t *allocator,
+ struct nexthop *nexthop)
+{
+ Fpm__SRv6LocalSID__EndDX6 *end_dx6;
+
+ end_dx6 = QPB_ALLOC(allocator, typeof(*end_dx6));
+ if (!end_dx6)
+ return NULL;
+
+ fpm__srv6_local_sid__end_dx6__init(end_dx6);
+
+ end_dx6->nexthop = fpm_nexthop_create(allocator, nexthop);
+
+ return end_dx6;
+}
+
+/*
+ * fpm__srv6_local_sid_end_dx4_behavior__create
+ */
+#define fpm_srv6_local_sid_end_dx4_behavior_create \
+ fpm__srv6_local_sid_end_dx4_behavior__create
+static inline Fpm__SRv6LocalSID__EndDX4 *
+fpm__srv6_local_sid_end_dx4_behavior__create(qpb_allocator_t *allocator,
+ struct nexthop *nexthop)
+{
+ Fpm__SRv6LocalSID__EndDX4 *end_dx4;
+
+ end_dx4 = QPB_ALLOC(allocator, typeof(*end_dx4));
+ if (!end_dx4)
+ return NULL;
+
+ fpm__srv6_local_sid__end_dx4__init(end_dx4);
+
+ end_dx4->nexthop = fpm_nexthop_create(allocator, nexthop);
+
+ return end_dx4;
+}
+
+/*
+ * fpm__srv6_local_sid_end_dt6_behavior__create
+ */
+#define fpm_srv6_local_sid_end_dt6_behavior_create \
+ fpm__srv6_local_sid_end_dt6_behavior__create
+static inline Fpm__SRv6LocalSID__EndDT6 *
+fpm__srv6_local_sid_end_dt6_behavior__create(qpb_allocator_t *allocator,
+ vrf_id_t vrf_id)
+{
+ Fpm__SRv6LocalSID__EndDT6 *end_dt6;
+
+ end_dt6 = QPB_ALLOC(allocator, typeof(*end_dt6));
+ if (!end_dt6)
+ return NULL;
+
+ fpm__srv6_local_sid__end_dt6__init(end_dt6);
+
+ end_dt6->vrf_id = vrf_id;
+
+ return end_dt6;
+}
+
+/*
+ * fpm__srv6_local_sid_end_dt4_behavior__create
+ */
+#define fpm_srv6_local_sid_end_dt4_behavior_create \
+ fpm__srv6_local_sid_end_dt4_behavior__create
+static inline Fpm__SRv6LocalSID__EndDT4 *
+fpm__srv6_local_sid_end_dt4_behavior__create(qpb_allocator_t *allocator,
+ vrf_id_t vrf_id)
+{
+ Fpm__SRv6LocalSID__EndDT4 *end_dt4;
+
+ end_dt4 = QPB_ALLOC(allocator, typeof(*end_dt4));
+ if (!end_dt4)
+ return NULL;
+
+ fpm__srv6_local_sid__end_dt4__init(end_dt4);
+
+ end_dt4->vrf_id = vrf_id;
+
+ return end_dt4;
+}
+
+/*
+ * fpm__srv6_local_sid_end_dt46_behavior__create
+ */
+#define fpm_srv6_local_sid_end_dt46_behavior_create \
+ fpm__srv6_local_sid_end_dt46_behavior__create
+static inline Fpm__SRv6LocalSID__EndDT46 *
+fpm__srv6_local_sid_end_dt46_behavior__create(qpb_allocator_t *allocator,
+ vrf_id_t vrf_id)
+{
+ Fpm__SRv6LocalSID__EndDT46 *end_dt46;
+
+ end_dt46 = QPB_ALLOC(allocator, typeof(*end_dt46));
+ if (!end_dt46)
+ return NULL;
+
+ fpm__srv6_local_sid__end_dt46__init(end_dt46);
+
+ end_dt46->vrf_id = vrf_id;
+
+ return end_dt46;
+}
+
+/*
+ * fpm__srv6_local_sid_un_behavior__create
+ */
+#define fpm_srv6_local_sid_un_behavior_create \
+ fpm__srv6_local_sid_un_behavior__create
+static inline Fpm__SRv6LocalSID__UN *
+fpm__srv6_local_sid_un_behavior__create(qpb_allocator_t *allocator)
+{
+ Fpm__SRv6LocalSID__UN *un;
+
+ un = QPB_ALLOC(allocator, typeof(*un));
+ if (!un)
+ return NULL;
+
+ fpm__srv6_local_sid__un__init(un);
+
+ return un;
+}
+
+/*
+ * fpm__srv6_local_sid_ua_behavior__create
+ */
+#define fpm_srv6_local_sid_ua_behavior_create \
+ fpm__srv6_local_sid_ua_behavior__create
+static inline Fpm__SRv6LocalSID__UA *
+fpm__srv6_local_sid_ua_behavior__create(qpb_allocator_t *allocator,
+ struct nexthop *nexthop)
+{
+ Fpm__SRv6LocalSID__UA *ua;
+
+ ua = QPB_ALLOC(allocator, typeof(*ua));
+ if (!ua)
+ return NULL;
+
+ fpm__srv6_local_sid__ua__init(ua);
+
+ ua->nexthop = fpm_nexthop_create(allocator, nexthop);
+
+ return ua;
+}
+
+/*
+ * fpm__srv6_local_sid_udt6_behavior__create
+ */
+#define fpm_srv6_local_sid_udt6_behavior_create \
+ fpm__srv6_local_sid_udt6_behavior__create
+static inline Fpm__SRv6LocalSID__UDT6 *
+fpm__srv6_local_sid_udt6_behavior__create(qpb_allocator_t *allocator,
+ vrf_id_t vrf_id)
+{
+ Fpm__SRv6LocalSID__UDT6 *udt6;
+
+ udt6 = QPB_ALLOC(allocator, typeof(*udt6));
+ if (!udt6)
+ return NULL;
+
+ fpm__srv6_local_sid__udt6__init(udt6);
+
+ udt6->vrf_id = vrf_id;
+
+ return udt6;
+}
+
+/*
+ * fpm__srv6_local_sid_udt4_behavior__create
+ */
+#define fpm_srv6_local_sid_udt4_behavior_create \
+ fpm__srv6_local_sid_udt4_behavior__create
+static inline Fpm__SRv6LocalSID__UDT4 *
+fpm__srv6_local_sid_udt4_behavior__create(qpb_allocator_t *allocator,
+ vrf_id_t vrf_id)
+{
+ Fpm__SRv6LocalSID__UDT4 *udt4;
+
+ udt4 = QPB_ALLOC(allocator, typeof(*udt4));
+ if (!udt4)
+ return NULL;
+
+ fpm__srv6_local_sid__udt4__init(udt4);
+
+ udt4->vrf_id = vrf_id;
+
+ return udt4;
+}
+
+/*
+ * fpm__srv6_local_sid_udt46_behavior__create
+ */
+#define fpm_srv6_local_sid_udt46_behavior_create \
+ fpm__srv6_local_sid_udt46_behavior__create
+static inline Fpm__SRv6LocalSID__UDT46 *
+fpm__srv6_local_sid_udt46_behavior__create(qpb_allocator_t *allocator,
+ vrf_id_t vrf_id)
+{
+ Fpm__SRv6LocalSID__UDT46 *udt46;
+
+ udt46 = QPB_ALLOC(allocator, typeof(*udt46));
+ if (!udt46)
+ return NULL;
+
+ fpm__srv6_local_sid__udt46__init(udt46);
+
+ udt46->vrf_id = vrf_id;
+
+ return udt46;
+}
+
#endif