diff options
Diffstat (limited to '')
-rw-r--r-- | fpm/fpm.proto | 145 | ||||
-rw-r--r-- | fpm/fpm_pb.c | 5 | ||||
-rw-r--r-- | fpm/fpm_pb.h | 400 |
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 |