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