]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_label.c
*: reindent
[mirror_frr.git] / bgpd / bgp_label.c
1 /* BGP carrying label information
2 * Copyright (C) 2013 Cumulus Networks, Inc.
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "command.h"
24 #include "thread.h"
25 #include "prefix.h"
26 #include "zclient.h"
27 #include "stream.h"
28 #include "network.h"
29 #include "log.h"
30 #include "memory.h"
31 #include "nexthop.h"
32 #include "mpls.h"
33
34 #include "bgpd/bgpd.h"
35 #include "bgpd/bgp_table.h"
36 #include "bgpd/bgp_route.h"
37 #include "bgpd/bgp_attr.h"
38 #include "bgpd/bgp_label.h"
39 #include "bgpd/bgp_packet.h"
40 #include "bgpd/bgp_debug.h"
41
42 extern struct zclient *zclient;
43
44 int bgp_parse_fec_update(void)
45 {
46 struct stream *s;
47 struct bgp_node *rn;
48 struct bgp *bgp;
49 struct bgp_table *table;
50 struct prefix p;
51 u_int32_t label;
52 afi_t afi;
53 safi_t safi;
54
55 s = zclient->ibuf;
56
57 memset(&p, 0, sizeof(struct prefix));
58 p.family = stream_getw(s);
59 p.prefixlen = stream_getc(s);
60 stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
61 label = stream_getl(s);
62
63 /* hack for the bgp instance & SAFI = have to send/receive it */
64 afi = family2afi(p.family);
65 safi = SAFI_UNICAST;
66 bgp = bgp_get_default();
67 if (!bgp) {
68 zlog_debug("no default bgp instance");
69 return -1;
70 }
71
72 table = bgp->rib[afi][safi];
73 if (!table) {
74 zlog_debug("no %u unicast table", p.family);
75 return -1;
76 }
77 rn = bgp_node_lookup(table, &p);
78 if (!rn) {
79 zlog_debug("no node for the prefix");
80 return -1;
81 }
82
83 /* treat it as implicit withdraw - the label is invalid */
84 if (label == MPLS_INVALID_LABEL)
85 bgp_unset_valid_label(&rn->local_label);
86 else {
87 label_ntop(label, 1, &rn->local_label);
88 bgp_set_valid_label(&rn->local_label);
89 }
90 SET_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED);
91 bgp_unlock_node(rn);
92 bgp_process(bgp, rn, afi, safi);
93 return 1;
94 }
95
96 mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
97 struct peer *to, afi_t afi, safi_t safi)
98 {
99 struct peer *from;
100 mpls_label_t remote_label;
101 int reflect;
102
103 if (!rn || !ri || !to)
104 return MPLS_INVALID_LABEL;
105
106 remote_label = ri->extra ? ri->extra->label : MPLS_INVALID_LABEL;
107 from = ri->peer;
108 reflect =
109 ((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP));
110
111 if (reflect
112 && !CHECK_FLAG(to->af_flags[afi][safi],
113 PEER_FLAG_FORCE_NEXTHOP_SELF))
114 return remote_label;
115
116 if (CHECK_FLAG(to->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED))
117 return remote_label;
118
119 return rn->local_label;
120 }
121
122 void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_info *ri, int reg)
123 {
124 struct stream *s;
125 struct prefix *p;
126 int command;
127 u_int16_t flags = 0;
128 size_t flags_pos = 0;
129
130 /* Check socket. */
131 if (!zclient || zclient->sock < 0)
132 return;
133
134 p = &(rn->p);
135 s = zclient->obuf;
136 stream_reset(s);
137 command = (reg) ? ZEBRA_FEC_REGISTER : ZEBRA_FEC_UNREGISTER;
138 zclient_create_header(s, command, VRF_DEFAULT);
139 flags_pos = stream_get_endp(s); /* save position of 'flags' */
140 stream_putw(s, flags); /* initial flags */
141 stream_putw(s, PREFIX_FAMILY(p));
142 stream_put_prefix(s, p);
143 if (reg) {
144 assert(ri);
145 if (ri->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
146 if (ri->attr->label_index != BGP_INVALID_LABEL_INDEX) {
147 flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX;
148 stream_putl(s, ri->attr->label_index);
149 }
150 }
151 SET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
152 } else
153 UNSET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
154
155 /* Set length and flags */
156 stream_putw_at(s, 0, stream_get_endp(s));
157 stream_putw_at(s, flags_pos, flags);
158
159 zclient_send_message(zclient);
160 }
161
162 static int bgp_nlri_get_labels(struct peer *peer, u_char *pnt, u_char plen,
163 mpls_label_t *label)
164 {
165 u_char *data = pnt;
166 u_char *lim = pnt + plen;
167 u_char llen = 0;
168 u_char label_depth = 0;
169
170 for (; data < lim; data += BGP_LABEL_BYTES) {
171 memcpy(label, data, BGP_LABEL_BYTES);
172 llen += BGP_LABEL_BYTES;
173
174 bgp_set_valid_label(label);
175 label_depth += 1;
176
177 if (bgp_is_withdraw_label(label) || label_bos(label))
178 break;
179 }
180
181 /* If we RX multiple labels we will end up keeping only the last
182 * one. We do not yet support a label stack greater than 1. */
183 if (label_depth > 1)
184 zlog_warn("%s rcvd UPDATE with label stack %d deep", peer->host,
185 label_depth);
186
187 if (!(bgp_is_withdraw_label(label) || label_bos(label)))
188 zlog_warn(
189 "%s rcvd UPDATE with invalid label stack - no bottom of stack",
190 peer->host);
191
192 return llen;
193 }
194
195 int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
196 struct bgp_nlri *packet)
197 {
198 u_char *pnt;
199 u_char *lim;
200 struct prefix p;
201 int psize = 0;
202 int prefixlen;
203 afi_t afi;
204 safi_t safi;
205 int addpath_encoded;
206 u_int32_t addpath_id;
207 mpls_label_t label = MPLS_INVALID_LABEL;
208 u_char llen;
209
210 /* Check peer status. */
211 if (peer->status != Established)
212 return 0;
213
214 pnt = packet->nlri;
215 lim = pnt + packet->length;
216 afi = packet->afi;
217 safi = packet->safi;
218 addpath_id = 0;
219
220 addpath_encoded =
221 (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
222 && CHECK_FLAG(peer->af_cap[afi][safi],
223 PEER_CAP_ADDPATH_AF_TX_RCV));
224
225 for (; pnt < lim; pnt += psize) {
226 /* Clear prefix structure. */
227 memset(&p, 0, sizeof(struct prefix));
228 llen = 0;
229
230 if (addpath_encoded) {
231
232 /* When packet overflow occurs return immediately. */
233 if (pnt + BGP_ADDPATH_ID_LEN > lim)
234 return -1;
235
236 addpath_id = ntohl(*((uint32_t *)pnt));
237 pnt += BGP_ADDPATH_ID_LEN;
238 }
239
240 /* Fetch prefix length. */
241 prefixlen = *pnt++;
242 p.family = afi2family(packet->afi);
243 psize = PSIZE(prefixlen);
244
245 /* sanity check against packet data */
246 if ((pnt + psize) > lim) {
247 zlog_err(
248 "%s [Error] Update packet error / L-U (prefix length %d exceeds packet size %u)",
249 peer->host, prefixlen, (uint)(lim - pnt));
250 return -1;
251 }
252
253 /* Fill in the labels */
254 llen = bgp_nlri_get_labels(peer, pnt, psize, &label);
255 p.prefixlen = prefixlen - BSIZE(llen);
256
257 /* There needs to be at least one label */
258 if (prefixlen < 24) {
259 zlog_err(
260 "%s [Error] Update packet error"
261 " (wrong label length %d)",
262 peer->host, prefixlen);
263 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
264 BGP_NOTIFY_UPDATE_INVAL_NETWORK);
265 return -1;
266 }
267
268 if ((afi == AFI_IP && p.prefixlen > 32)
269 || (afi == AFI_IP6 && p.prefixlen > 128))
270 return -1;
271
272 /* Fetch prefix from NLRI packet */
273 memcpy(&p.u.prefix, pnt + llen, psize - llen);
274
275 /* Check address. */
276 if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST) {
277 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
278 /* From RFC4271 Section 6.3:
279 *
280 * If a prefix in the NLRI field is semantically
281 * incorrect
282 * (e.g., an unexpected multicast IP address),
283 * an error SHOULD
284 * be logged locally, and the prefix SHOULD be
285 * ignored.
286 */
287 zlog_err(
288 "%s: IPv4 labeled-unicast NLRI is multicast address %s, ignoring",
289 peer->host, inet_ntoa(p.u.prefix4));
290 continue;
291 }
292 }
293
294 /* Check address. */
295 if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST) {
296 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
297 char buf[BUFSIZ];
298
299 zlog_err(
300 "%s: IPv6 labeled-unicast NLRI is link-local address %s, ignoring",
301 peer->host,
302 inet_ntop(AF_INET6, &p.u.prefix6, buf,
303 BUFSIZ));
304
305 continue;
306 }
307
308 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
309 char buf[BUFSIZ];
310
311 zlog_err(
312 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
313 peer->host,
314 inet_ntop(AF_INET6, &p.u.prefix6, buf,
315 BUFSIZ));
316
317 continue;
318 }
319 }
320
321 if (attr) {
322 bgp_update(peer, &p, addpath_id, attr, packet->afi,
323 SAFI_UNICAST, ZEBRA_ROUTE_BGP,
324 BGP_ROUTE_NORMAL, NULL, &label, 0, NULL);
325 } else {
326 bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
327 SAFI_UNICAST, ZEBRA_ROUTE_BGP,
328 BGP_ROUTE_NORMAL, NULL, &label, NULL);
329 }
330 }
331
332 /* Packet length consistency check. */
333 if (pnt != lim) {
334 zlog_err(
335 "%s [Error] Update packet error / L-U (%zu data remaining after parsing)",
336 peer->host, lim - pnt);
337 return -1;
338 }
339
340 return 0;
341 }