xref: /openbsd-src/usr.sbin/ldpd/l2vpn.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: l2vpn.c,v 1.21 2016/07/01 23:36:38 renato Exp $ */
2 
3 /*
4  * Copyright (c) 2015 Renato Westphal <renato@openbsd.org>
5  * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
6  * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
7  * Copyright (c) 2004, 2005, 2008 Esben Norby <norby@openbsd.org>
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 #include <sys/types.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <limits.h>
26 
27 #include "ldpd.h"
28 #include "ldpe.h"
29 #include "lde.h"
30 #include "log.h"
31 
32 static void	 l2vpn_pw_fec(struct l2vpn_pw *, struct fec *);
33 
34 struct l2vpn *
35 l2vpn_new(const char *name)
36 {
37 	struct l2vpn	*l2vpn;
38 
39 	if ((l2vpn = calloc(1, sizeof(*l2vpn))) == NULL)
40 		fatal("l2vpn_new: calloc");
41 
42 	strlcpy(l2vpn->name, name, sizeof(l2vpn->name));
43 
44 	/* set default values */
45 	l2vpn->mtu = DEFAULT_L2VPN_MTU;
46 	l2vpn->pw_type = DEFAULT_PW_TYPE;
47 
48 	LIST_INIT(&l2vpn->if_list);
49 	LIST_INIT(&l2vpn->pw_list);
50 
51 	return (l2vpn);
52 }
53 
54 struct l2vpn *
55 l2vpn_find(struct ldpd_conf *xconf, const char *name)
56 {
57 	struct l2vpn	*l2vpn;
58 
59 	LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry)
60 		if (strcmp(l2vpn->name, name) == 0)
61 			return (l2vpn);
62 
63 	return (NULL);
64 }
65 
66 void
67 l2vpn_del(struct l2vpn *l2vpn)
68 {
69 	struct l2vpn_if		*lif;
70 	struct l2vpn_pw		*pw;
71 
72 	while ((lif = LIST_FIRST(&l2vpn->if_list)) != NULL) {
73 		LIST_REMOVE(lif, entry);
74 		free(lif);
75 	}
76 	while ((pw = LIST_FIRST(&l2vpn->pw_list)) != NULL) {
77 		LIST_REMOVE(pw, entry);
78 		free(pw);
79 	}
80 
81 	free(l2vpn);
82 }
83 
84 void
85 l2vpn_init(struct l2vpn *l2vpn)
86 {
87 	struct l2vpn_pw	*pw;
88 
89 	LIST_FOREACH(pw, &l2vpn->pw_list, entry)
90 		l2vpn_pw_init(pw);
91 }
92 
93 void
94 l2vpn_exit(struct l2vpn *l2vpn)
95 {
96 	struct l2vpn_pw		*pw;
97 
98 	LIST_FOREACH(pw, &l2vpn->pw_list, entry)
99 		l2vpn_pw_exit(pw);
100 }
101 
102 struct l2vpn_if *
103 l2vpn_if_new(struct l2vpn *l2vpn, struct kif *kif)
104 {
105 	struct l2vpn_if	*lif;
106 
107 	if ((lif = calloc(1, sizeof(*lif))) == NULL)
108 		fatal("l2vpn_if_new: calloc");
109 
110 	lif->l2vpn = l2vpn;
111 	strlcpy(lif->ifname, kif->ifname, sizeof(lif->ifname));
112 	lif->ifindex = kif->ifindex;
113 	lif->flags = kif->flags;
114 	lif->link_state = kif->link_state;
115 
116 	return (lif);
117 }
118 
119 struct l2vpn_if *
120 l2vpn_if_find(struct l2vpn *l2vpn, unsigned int ifindex)
121 {
122 	struct l2vpn_if	*lif;
123 
124 	LIST_FOREACH(lif, &l2vpn->if_list, entry)
125 		if (lif->ifindex == ifindex)
126 			return (lif);
127 
128 	return (NULL);
129 }
130 
131 struct l2vpn_pw *
132 l2vpn_pw_new(struct l2vpn *l2vpn, struct kif *kif)
133 {
134 	struct l2vpn_pw	*pw;
135 
136 	if ((pw = calloc(1, sizeof(*pw))) == NULL)
137 		fatal("l2vpn_pw_new: calloc");
138 
139 	pw->l2vpn = l2vpn;
140 	strlcpy(pw->ifname, kif->ifname, sizeof(pw->ifname));
141 	pw->ifindex = kif->ifindex;
142 
143 	return (pw);
144 }
145 
146 struct l2vpn_pw *
147 l2vpn_pw_find(struct l2vpn *l2vpn, unsigned int ifindex)
148 {
149 	struct l2vpn_pw	*pw;
150 
151 	LIST_FOREACH(pw, &l2vpn->pw_list, entry)
152 		if (pw->ifindex == ifindex)
153 			return (pw);
154 
155 	return (NULL);
156 }
157 
158 void
159 l2vpn_pw_init(struct l2vpn_pw *pw)
160 {
161 	struct fec	 fec;
162 
163 	l2vpn_pw_reset(pw);
164 
165 	l2vpn_pw_fec(pw, &fec);
166 	lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0,
167 	    0, (void *)pw);
168 }
169 
170 void
171 l2vpn_pw_exit(struct l2vpn_pw *pw)
172 {
173 	struct fec	 fec;
174 
175 	l2vpn_pw_fec(pw, &fec);
176 	lde_kernel_remove(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0);
177 }
178 
179 static void
180 l2vpn_pw_fec(struct l2vpn_pw *pw, struct fec *fec)
181 {
182 	memset(fec, 0, sizeof(*fec));
183 	fec->type = FEC_TYPE_PWID;
184 	fec->u.pwid.type = pw->l2vpn->pw_type;
185 	fec->u.pwid.pwid = pw->pwid;
186 	fec->u.pwid.lsr_id = pw->lsr_id;
187 }
188 
189 void
190 l2vpn_pw_reset(struct l2vpn_pw *pw)
191 {
192 	pw->remote_group = 0;
193 	pw->remote_mtu = 0;
194 	pw->remote_status = 0;
195 
196 	if (pw->flags & F_PW_CWORD_CONF)
197 		pw->flags |= F_PW_CWORD;
198 	else
199 		pw->flags &= ~F_PW_CWORD;
200 
201 	if (pw->flags & F_PW_STATUSTLV_CONF)
202 		pw->flags |= F_PW_STATUSTLV;
203 	else
204 		pw->flags &= ~F_PW_STATUSTLV;
205 }
206 
207 int
208 l2vpn_pw_ok(struct l2vpn_pw *pw, struct fec_nh *fnh)
209 {
210 	struct fec		 fec;
211 	struct fec_node		*fn;
212 
213 	/* check for a remote label */
214 	if (fnh->remote_label == NO_LABEL)
215 		return (0);
216 
217 	/* MTUs must match */
218 	if (pw->l2vpn->mtu != pw->remote_mtu)
219 		return (0);
220 
221 	/* check pw status if applicable */
222 	if ((pw->flags & F_PW_STATUSTLV) &&
223 	    pw->remote_status != PW_FORWARDING)
224 		return (0);
225 
226 	/* check for a working lsp to the nexthop */
227 	memset(&fec, 0, sizeof(fec));
228 	switch (pw->af) {
229 	case AF_INET:
230 		fec.type = FEC_TYPE_IPV4;
231 		fec.u.ipv4.prefix = pw->addr.v4;
232 		fec.u.ipv4.prefixlen = 32;
233 		break;
234 	case AF_INET6:
235 		fec.type = FEC_TYPE_IPV6;
236 		fec.u.ipv6.prefix = pw->addr.v6;
237 		fec.u.ipv6.prefixlen = 128;
238 		break;
239 	default:
240 		fatalx("l2vpn_pw_ok: unknown af");
241 	}
242 
243 	fn = (struct fec_node *)fec_find(&ft, &fec);
244 	if (fn == NULL || fn->local_label == NO_LABEL)
245 		return (0);
246 	/*
247 	 * Need to ensure that there's a label binding for all nexthops.
248 	 * Otherwise, ECMP for this route could render the pseudowire unusable.
249 	 */
250 	LIST_FOREACH(fnh, &fn->nexthops, entry)
251 		if (fnh->remote_label == NO_LABEL)
252 			return (0);
253 
254 	return (1);
255 }
256 
257 int
258 l2vpn_pw_negotiate(struct lde_nbr *ln, struct fec_node *fn, struct map *map)
259 {
260 	struct l2vpn_pw		*pw;
261 	struct status_tlv	 st;
262 
263 	/* NOTE: thanks martini & friends for all this mess */
264 
265 	pw = (struct l2vpn_pw *) fn->data;
266 	if (pw == NULL)
267 		/*
268 		 * pseudowire not configured, return and record
269 		 * the mapping later
270 		 */
271 		return (0);
272 
273 	/* RFC4447 - Section 6.2: control word negotiation */
274 	if (fec_find(&ln->sent_map, &fn->fec)) {
275 		if ((map->flags & F_MAP_PW_CWORD) &&
276 		    !(pw->flags & F_PW_CWORD_CONF)) {
277 			/* ignore the received label mapping */
278 			return (1);
279 		} else if (!(map->flags & F_MAP_PW_CWORD) &&
280 		    (pw->flags & F_PW_CWORD_CONF)) {
281 			/* append a "Wrong C-bit" status code */
282 			st.status_code = S_WRONG_CBIT;
283 			st.msg_id = map->msg_id;
284 			st.msg_type = htons(MSG_TYPE_LABELMAPPING);
285 			lde_send_labelwithdraw(ln, fn, NO_LABEL, &st);
286 
287 			pw->flags &= ~F_PW_CWORD;
288 			lde_send_labelmapping(ln, fn, 1);
289 		}
290 	} else if (map->flags & F_MAP_PW_CWORD) {
291 		if (pw->flags & F_PW_CWORD_CONF)
292 			pw->flags |= F_PW_CWORD;
293 		else
294 			/* act as if no label mapping had been received */
295 			return (1);
296 	} else
297 		pw->flags &= ~F_PW_CWORD;
298 
299 	/* RFC4447 - Section 5.4.3: pseudowire status negotiation */
300 	if (fec_find(&ln->recv_map, &fn->fec) == NULL &&
301 	    !(map->flags & F_MAP_PW_STATUS))
302 		pw->flags &= ~F_PW_STATUSTLV;
303 
304 	return (0);
305 }
306 
307 void
308 l2vpn_send_pw_status(uint32_t peerid, uint32_t status, struct fec *fec)
309 {
310 	struct notify_msg	 nm;
311 
312 	memset(&nm, 0, sizeof(nm));
313 	nm.status_code = S_PW_STATUS;
314 	nm.pw_status = status;
315 	nm.flags |= F_NOTIF_PW_STATUS;
316 	lde_fec2map(fec, &nm.fec);
317 	nm.flags |= F_NOTIF_FEC;
318 
319 	lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, peerid, 0,
320 	    &nm, sizeof(nm));
321 }
322 
323 void
324 l2vpn_recv_pw_status(struct lde_nbr *ln, struct notify_msg *nm)
325 {
326 	struct fec		 fec;
327 	struct fec_node		*fn;
328 	struct fec_nh		*fnh;
329 	struct l2vpn_pw		*pw;
330 
331 	/* TODO group wildcard */
332 	if (!(nm->fec.flags & F_MAP_PW_ID))
333 		return;
334 
335 	lde_map2fec(&nm->fec, ln->id, &fec);
336 	fn = (struct fec_node *)fec_find(&ft, &fec);
337 	if (fn == NULL)
338 		/* unknown fec */
339 		return;
340 
341 	pw = (struct l2vpn_pw *) fn->data;
342 	if (pw == NULL)
343 		return;
344 
345 	fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id, 0);
346 	if (fnh == NULL)
347 		return;
348 
349 	/* remote status didn't change */
350 	if (pw->remote_status == nm->pw_status)
351 		return;
352 
353 	pw->remote_status = nm->pw_status;
354 
355 	if (l2vpn_pw_ok(pw, fnh))
356 		lde_send_change_klabel(fn, fnh);
357 	else
358 		lde_send_delete_klabel(fn, fnh);
359 }
360 
361 void
362 l2vpn_sync_pws(int af, union ldpd_addr *addr)
363 {
364 	struct l2vpn		*l2vpn;
365 	struct l2vpn_pw		*pw;
366 	struct fec		 fec;
367 	struct fec_node		*fn;
368 	struct fec_nh		*fnh;
369 
370 	LIST_FOREACH(l2vpn, &ldeconf->l2vpn_list, entry) {
371 		LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
372 			if (af != pw->af || ldp_addrcmp(af, &pw->addr, addr))
373 				continue;
374 
375 			l2vpn_pw_fec(pw, &fec);
376 			fn = (struct fec_node *)fec_find(&ft, &fec);
377 			if (fn == NULL)
378 				continue;
379 			fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)
380 			    &pw->lsr_id, 0);
381 			if (fnh == NULL)
382 				continue;
383 
384 			if (l2vpn_pw_ok(pw, fnh))
385 				lde_send_change_klabel(fn, fnh);
386 			else
387 				lde_send_delete_klabel(fn, fnh);
388 		}
389 	}
390 }
391 
392 void
393 l2vpn_pw_ctl(pid_t pid)
394 {
395 	struct l2vpn		*l2vpn;
396 	struct l2vpn_pw		*pw;
397 	static struct ctl_pw	 pwctl;
398 
399 	LIST_FOREACH(l2vpn, &ldeconf->l2vpn_list, entry)
400 		LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
401 			memset(&pwctl, 0, sizeof(pwctl));
402 			strlcpy(pwctl.ifname, pw->ifname,
403 			    sizeof(pwctl.ifname));
404 			pwctl.pwid = pw->pwid;
405 			pwctl.lsr_id = pw->lsr_id;
406 			pwctl.status = pw->flags & F_PW_STATUS_UP;
407 
408 			lde_imsg_compose_ldpe(IMSG_CTL_SHOW_L2VPN_PW, 0,
409 			    pid, &pwctl, sizeof(pwctl));
410 		}
411 }
412 
413 void
414 l2vpn_binding_ctl(pid_t pid)
415 {
416 	struct fec		*f;
417 	struct fec_node		*fn;
418 	struct lde_map		*me;
419 	struct l2vpn_pw		*pw;
420 	static struct ctl_pw	 pwctl;
421 
422 	RB_FOREACH(f, fec_tree, &ft) {
423 		if (f->type != FEC_TYPE_PWID)
424 			continue;
425 
426 		fn = (struct fec_node *)f;
427 		if (fn->local_label == NO_LABEL &&
428 		    LIST_EMPTY(&fn->downstream))
429 			continue;
430 
431 		memset(&pwctl, 0, sizeof(pwctl));
432 		pwctl.type = f->u.pwid.type;
433 		pwctl.pwid = f->u.pwid.pwid;
434 		pwctl.lsr_id = f->u.pwid.lsr_id;
435 
436 		pw = (struct l2vpn_pw *) fn->data;
437 		if (pw) {
438 			pwctl.local_label = fn->local_label;
439 			pwctl.local_gid = 0;
440 			pwctl.local_ifmtu = pw->l2vpn->mtu;
441 		} else
442 			pwctl.local_label = NO_LABEL;
443 
444 		LIST_FOREACH(me, &fn->downstream, entry)
445 			if (f->u.pwid.lsr_id.s_addr == me->nexthop->id.s_addr)
446 				break;
447 
448 		if (me) {
449 			pwctl.remote_label = me->map.label;
450 			pwctl.remote_gid = me->map.fec.pwid.group_id;
451 			if (me->map.flags & F_MAP_PW_IFMTU)
452 				pwctl.remote_ifmtu = me->map.fec.pwid.ifmtu;
453 
454 			lde_imsg_compose_ldpe(IMSG_CTL_SHOW_L2VPN_BINDING,
455 			    0, pid, &pwctl, sizeof(pwctl));
456 		} else if (pw) {
457 			pwctl.remote_label = NO_LABEL;
458 
459 			lde_imsg_compose_ldpe(IMSG_CTL_SHOW_L2VPN_BINDING,
460 			    0, pid, &pwctl, sizeof(pwctl));
461 		}
462 	}
463 }
464 
465 /* ldpe */
466 
467 void
468 ldpe_l2vpn_init(struct l2vpn *l2vpn)
469 {
470 	struct l2vpn_pw		*pw;
471 
472 	LIST_FOREACH(pw, &l2vpn->pw_list, entry)
473 		ldpe_l2vpn_pw_init(pw);
474 }
475 
476 void
477 ldpe_l2vpn_exit(struct l2vpn *l2vpn)
478 {
479 	struct l2vpn_pw		*pw;
480 
481 	LIST_FOREACH(pw, &l2vpn->pw_list, entry)
482 		ldpe_l2vpn_pw_exit(pw);
483 }
484 
485 void
486 ldpe_l2vpn_pw_init(struct l2vpn_pw *pw)
487 {
488 	struct tnbr		*tnbr;
489 
490 	tnbr = tnbr_find(leconf, pw->af, &pw->addr);
491 	if (tnbr == NULL) {
492 		tnbr = tnbr_new(leconf, pw->af, &pw->addr);
493 		tnbr_update(tnbr);
494 		LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry);
495 	}
496 
497 	tnbr->pw_count++;
498 }
499 
500 void
501 ldpe_l2vpn_pw_exit(struct l2vpn_pw *pw)
502 {
503 	struct tnbr		*tnbr;
504 
505 	tnbr = tnbr_find(leconf, pw->af, &pw->addr);
506 	if (tnbr) {
507 		tnbr->pw_count--;
508 		tnbr_check(tnbr);
509 	}
510 }
511