Line data Source code
1 : /*
2 : * SRv6 definitions
3 : * Copyright (C) 2020 Hiroki Shirokura, LINE Corporation
4 : *
5 : * This program is free software; you can redistribute it and/or modify it
6 : * under the terms of the GNU General Public License as published by the Free
7 : * Software Foundation; either version 2 of the License, or (at your option)
8 : * any later version.
9 : *
10 : * This program is distributed in the hope that it will be useful, but WITHOUT
11 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 : * more details.
14 : *
15 : * You should have received a copy of the GNU General Public License along
16 : * with this program; see the file COPYING; if not, write to the Free Software
17 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 : */
19 :
20 : #ifndef _FRR_SRV6_H
21 : #define _FRR_SRV6_H
22 :
23 : #include <zebra.h>
24 : #include "prefix.h"
25 : #include "json.h"
26 :
27 : #include <arpa/inet.h>
28 : #include <netinet/in.h>
29 :
30 : #define SRV6_MAX_SIDS 16
31 : #define SRV6_LOCNAME_SIZE 256
32 :
33 : #ifdef __cplusplus
34 : extern "C" {
35 : #endif
36 :
37 : #define sid2str(sid, str, size) \
38 : inet_ntop(AF_INET6, sid, str, size)
39 :
40 : enum seg6_mode_t {
41 : INLINE,
42 : ENCAP,
43 : L2ENCAP,
44 : };
45 :
46 : enum seg6local_action_t {
47 : ZEBRA_SEG6_LOCAL_ACTION_UNSPEC = 0,
48 : ZEBRA_SEG6_LOCAL_ACTION_END = 1,
49 : ZEBRA_SEG6_LOCAL_ACTION_END_X = 2,
50 : ZEBRA_SEG6_LOCAL_ACTION_END_T = 3,
51 : ZEBRA_SEG6_LOCAL_ACTION_END_DX2 = 4,
52 : ZEBRA_SEG6_LOCAL_ACTION_END_DX6 = 5,
53 : ZEBRA_SEG6_LOCAL_ACTION_END_DX4 = 6,
54 : ZEBRA_SEG6_LOCAL_ACTION_END_DT6 = 7,
55 : ZEBRA_SEG6_LOCAL_ACTION_END_DT4 = 8,
56 : ZEBRA_SEG6_LOCAL_ACTION_END_B6 = 9,
57 : ZEBRA_SEG6_LOCAL_ACTION_END_B6_ENCAP = 10,
58 : ZEBRA_SEG6_LOCAL_ACTION_END_BM = 11,
59 : ZEBRA_SEG6_LOCAL_ACTION_END_S = 12,
60 : ZEBRA_SEG6_LOCAL_ACTION_END_AS = 13,
61 : ZEBRA_SEG6_LOCAL_ACTION_END_AM = 14,
62 : ZEBRA_SEG6_LOCAL_ACTION_END_BPF = 15,
63 : ZEBRA_SEG6_LOCAL_ACTION_END_DT46 = 16,
64 : };
65 :
66 : struct seg6_segs {
67 : size_t num_segs;
68 : struct in6_addr segs[256];
69 : };
70 :
71 : struct seg6local_context {
72 : struct in_addr nh4;
73 : struct in6_addr nh6;
74 : uint32_t table;
75 : };
76 :
77 : struct srv6_locator {
78 : char name[SRV6_LOCNAME_SIZE];
79 : struct prefix_ipv6 prefix;
80 :
81 : /*
82 : * Bit length of SRv6 locator described in
83 : * draft-ietf-bess-srv6-services-05#section-3.2.1
84 : */
85 : uint8_t block_bits_length;
86 : uint8_t node_bits_length;
87 : uint8_t function_bits_length;
88 : uint8_t argument_bits_length;
89 :
90 : int algonum;
91 : uint64_t current;
92 : bool status_up;
93 : struct list *chunks;
94 :
95 : uint8_t flags;
96 : #define SRV6_LOCATOR_USID (1 << 0) /* The SRv6 Locator is a uSID Locator */
97 :
98 : QOBJ_FIELDS;
99 : };
100 : DECLARE_QOBJ_TYPE(srv6_locator);
101 :
102 : struct srv6_locator_chunk {
103 : char locator_name[SRV6_LOCNAME_SIZE];
104 : struct prefix_ipv6 prefix;
105 :
106 : /*
107 : * Bit length of SRv6 locator described in
108 : * draft-ietf-bess-srv6-services-05#section-3.2.1
109 : */
110 : uint8_t block_bits_length;
111 : uint8_t node_bits_length;
112 : uint8_t function_bits_length;
113 : uint8_t argument_bits_length;
114 :
115 : /*
116 : * For Zclient communication values
117 : */
118 : uint8_t keep;
119 : uint8_t proto;
120 : uint16_t instance;
121 : uint32_t session_id;
122 :
123 : uint8_t flags;
124 : };
125 :
126 : /*
127 : * SRv6 Endpoint Behavior codepoints, as defined by IANA in
128 : * https://www.iana.org/assignments/segment-routing/segment-routing.xhtml
129 : */
130 : enum srv6_endpoint_behavior_codepoint {
131 : SRV6_ENDPOINT_BEHAVIOR_RESERVED = 0x0000,
132 : SRV6_ENDPOINT_BEHAVIOR_END_DT6 = 0x0012,
133 : SRV6_ENDPOINT_BEHAVIOR_END_DT4 = 0x0013,
134 : SRV6_ENDPOINT_BEHAVIOR_END_DT46 = 0x0014,
135 : SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID = 0x003E,
136 : SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID = 0x003F,
137 : SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID = 0x0040,
138 : SRV6_ENDPOINT_BEHAVIOR_OPAQUE = 0xFFFF,
139 : };
140 :
141 : struct nexthop_srv6 {
142 : /* SRv6 localsid info for Endpoint-behaviour */
143 : enum seg6local_action_t seg6local_action;
144 : struct seg6local_context seg6local_ctx;
145 :
146 : /* SRv6 Headend-behaviour */
147 : struct in6_addr seg6_segs;
148 : };
149 :
150 : static inline const char *seg6_mode2str(enum seg6_mode_t mode)
151 : {
152 : switch (mode) {
153 : case INLINE:
154 : return "INLINE";
155 : case ENCAP:
156 : return "ENCAP";
157 : case L2ENCAP:
158 : return "L2ENCAP";
159 : default:
160 : return "unknown";
161 : }
162 : }
163 :
164 1 : static inline bool sid_same(
165 : const struct in6_addr *a,
166 : const struct in6_addr *b)
167 : {
168 1 : if (!a && !b)
169 : return true;
170 1 : else if (!(a && b))
171 : return false;
172 : else
173 1 : return memcmp(a, b, sizeof(struct in6_addr)) == 0;
174 : }
175 :
176 : static inline bool sid_diff(
177 : const struct in6_addr *a,
178 : const struct in6_addr *b)
179 : {
180 : return !sid_same(a, b);
181 : }
182 :
183 1 : static inline bool sid_zero(
184 : const struct in6_addr *a)
185 : {
186 1 : struct in6_addr zero = {};
187 :
188 1 : return sid_same(a, &zero);
189 : }
190 :
191 : static inline void *sid_copy(struct in6_addr *dst,
192 : const struct in6_addr *src)
193 : {
194 : return memcpy(dst, src, sizeof(struct in6_addr));
195 : }
196 :
197 : const char *
198 : seg6local_action2str(uint32_t action);
199 :
200 : const char *seg6local_context2str(char *str, size_t size,
201 : const struct seg6local_context *ctx,
202 : uint32_t action);
203 :
204 : int snprintf_seg6_segs(char *str,
205 : size_t size, const struct seg6_segs *segs);
206 :
207 : extern struct srv6_locator *srv6_locator_alloc(const char *name);
208 : extern struct srv6_locator_chunk *srv6_locator_chunk_alloc(void);
209 : extern void srv6_locator_free(struct srv6_locator *locator);
210 : extern void srv6_locator_chunk_free(struct srv6_locator_chunk **chunk);
211 : json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk);
212 : json_object *srv6_locator_json(const struct srv6_locator *loc);
213 : json_object *srv6_locator_detailed_json(const struct srv6_locator *loc);
214 : json_object *
215 : srv6_locator_chunk_detailed_json(const struct srv6_locator_chunk *chunk);
216 :
217 : #ifdef __cplusplus
218 : }
219 : #endif
220 :
221 : #endif
|