1 /* $OpenBSD: l2vpn.c,v 1.24 2017/03/04 00:21: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 <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->linkstate = 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 void 132 l2vpn_if_update(struct l2vpn_if *lif) 133 { 134 struct l2vpn *l2vpn = lif->l2vpn; 135 struct l2vpn_pw *pw; 136 struct map fec; 137 struct nbr *nbr; 138 139 if ((lif->flags & IFF_UP) && LINK_STATE_IS_UP(lif->linkstate)) 140 return; 141 142 LIST_FOREACH(pw, &l2vpn->pw_list, entry) { 143 nbr = nbr_find_ldpid(pw->lsr_id.s_addr); 144 if (nbr == NULL) 145 continue; 146 147 memset(&fec, 0, sizeof(fec)); 148 fec.type = MAP_TYPE_PWID; 149 fec.fec.pwid.type = l2vpn->pw_type; 150 fec.fec.pwid.group_id = 0; 151 fec.flags |= F_MAP_PW_ID; 152 fec.fec.pwid.pwid = pw->pwid; 153 154 send_mac_withdrawal(nbr, &fec, lif->mac); 155 } 156 } 157 158 struct l2vpn_pw * 159 l2vpn_pw_new(struct l2vpn *l2vpn, struct kif *kif) 160 { 161 struct l2vpn_pw *pw; 162 163 if ((pw = calloc(1, sizeof(*pw))) == NULL) 164 fatal("l2vpn_pw_new: calloc"); 165 166 pw->l2vpn = l2vpn; 167 strlcpy(pw->ifname, kif->ifname, sizeof(pw->ifname)); 168 pw->ifindex = kif->ifindex; 169 170 return (pw); 171 } 172 173 struct l2vpn_pw * 174 l2vpn_pw_find(struct l2vpn *l2vpn, unsigned int ifindex) 175 { 176 struct l2vpn_pw *pw; 177 178 LIST_FOREACH(pw, &l2vpn->pw_list, entry) 179 if (pw->ifindex == ifindex) 180 return (pw); 181 182 return (NULL); 183 } 184 185 void 186 l2vpn_pw_init(struct l2vpn_pw *pw) 187 { 188 struct fec fec; 189 190 l2vpn_pw_reset(pw); 191 192 l2vpn_pw_fec(pw, &fec); 193 lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 194 0, (void *)pw); 195 } 196 197 void 198 l2vpn_pw_exit(struct l2vpn_pw *pw) 199 { 200 struct fec fec; 201 202 l2vpn_pw_fec(pw, &fec); 203 lde_kernel_remove(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0); 204 } 205 206 static void 207 l2vpn_pw_fec(struct l2vpn_pw *pw, struct fec *fec) 208 { 209 memset(fec, 0, sizeof(*fec)); 210 fec->type = FEC_TYPE_PWID; 211 fec->u.pwid.type = pw->l2vpn->pw_type; 212 fec->u.pwid.pwid = pw->pwid; 213 fec->u.pwid.lsr_id = pw->lsr_id; 214 } 215 216 void 217 l2vpn_pw_reset(struct l2vpn_pw *pw) 218 { 219 pw->remote_group = 0; 220 pw->remote_mtu = 0; 221 pw->remote_status = 0; 222 223 if (pw->flags & F_PW_CWORD_CONF) 224 pw->flags |= F_PW_CWORD; 225 else 226 pw->flags &= ~F_PW_CWORD; 227 228 if (pw->flags & F_PW_STATUSTLV_CONF) 229 pw->flags |= F_PW_STATUSTLV; 230 else 231 pw->flags &= ~F_PW_STATUSTLV; 232 } 233 234 int 235 l2vpn_pw_ok(struct l2vpn_pw *pw, struct fec_nh *fnh) 236 { 237 struct fec fec; 238 struct fec_node *fn; 239 240 /* check for a remote label */ 241 if (fnh->remote_label == NO_LABEL) 242 return (0); 243 244 /* MTUs must match */ 245 if (pw->l2vpn->mtu != pw->remote_mtu) 246 return (0); 247 248 /* check pw status if applicable */ 249 if ((pw->flags & F_PW_STATUSTLV) && 250 pw->remote_status != PW_FORWARDING) 251 return (0); 252 253 /* check for a working lsp to the nexthop */ 254 memset(&fec, 0, sizeof(fec)); 255 switch (pw->af) { 256 case AF_INET: 257 fec.type = FEC_TYPE_IPV4; 258 fec.u.ipv4.prefix = pw->addr.v4; 259 fec.u.ipv4.prefixlen = 32; 260 break; 261 case AF_INET6: 262 fec.type = FEC_TYPE_IPV6; 263 fec.u.ipv6.prefix = pw->addr.v6; 264 fec.u.ipv6.prefixlen = 128; 265 break; 266 default: 267 fatalx("l2vpn_pw_ok: unknown af"); 268 } 269 270 fn = (struct fec_node *)fec_find(&ft, &fec); 271 if (fn == NULL || fn->local_label == NO_LABEL) 272 return (0); 273 /* 274 * Need to ensure that there's a label binding for all nexthops. 275 * Otherwise, ECMP for this route could render the pseudowire unusable. 276 */ 277 LIST_FOREACH(fnh, &fn->nexthops, entry) 278 if (fnh->remote_label == NO_LABEL) 279 return (0); 280 281 return (1); 282 } 283 284 int 285 l2vpn_pw_negotiate(struct lde_nbr *ln, struct fec_node *fn, struct map *map) 286 { 287 struct l2vpn_pw *pw; 288 struct status_tlv st; 289 290 /* NOTE: thanks martini & friends for all this mess */ 291 292 pw = (struct l2vpn_pw *) fn->data; 293 if (pw == NULL) 294 /* 295 * pseudowire not configured, return and record 296 * the mapping later 297 */ 298 return (0); 299 300 /* RFC4447 - Section 6.2: control word negotiation */ 301 if (fec_find(&ln->sent_map, &fn->fec)) { 302 if ((map->flags & F_MAP_PW_CWORD) && 303 !(pw->flags & F_PW_CWORD_CONF)) { 304 /* ignore the received label mapping */ 305 return (1); 306 } else if (!(map->flags & F_MAP_PW_CWORD) && 307 (pw->flags & F_PW_CWORD_CONF)) { 308 /* append a "Wrong C-bit" status code */ 309 st.status_code = S_WRONG_CBIT; 310 st.msg_id = map->msg_id; 311 st.msg_type = htons(MSG_TYPE_LABELMAPPING); 312 lde_send_labelwithdraw(ln, fn, NULL, &st); 313 314 pw->flags &= ~F_PW_CWORD; 315 lde_send_labelmapping(ln, fn, 1); 316 } 317 } else if (map->flags & F_MAP_PW_CWORD) { 318 if (pw->flags & F_PW_CWORD_CONF) 319 pw->flags |= F_PW_CWORD; 320 else 321 /* act as if no label mapping had been received */ 322 return (1); 323 } else 324 pw->flags &= ~F_PW_CWORD; 325 326 /* RFC4447 - Section 5.4.3: pseudowire status negotiation */ 327 if (fec_find(&ln->recv_map, &fn->fec) == NULL && 328 !(map->flags & F_MAP_PW_STATUS)) 329 pw->flags &= ~F_PW_STATUSTLV; 330 331 return (0); 332 } 333 334 void 335 l2vpn_send_pw_status(struct lde_nbr *ln, uint32_t status, struct fec *fec) 336 { 337 struct notify_msg nm; 338 339 memset(&nm, 0, sizeof(nm)); 340 nm.status_code = S_PW_STATUS; 341 nm.pw_status = status; 342 nm.flags |= F_NOTIF_PW_STATUS; 343 lde_fec2map(fec, &nm.fec); 344 nm.flags |= F_NOTIF_FEC; 345 346 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0, &nm, 347 sizeof(nm)); 348 } 349 350 void 351 l2vpn_send_pw_status_wcard(struct lde_nbr *ln, uint32_t status, 352 uint16_t pw_type, uint32_t group_id) 353 { 354 struct notify_msg nm; 355 356 memset(&nm, 0, sizeof(nm)); 357 nm.status_code = S_PW_STATUS; 358 nm.pw_status = status; 359 nm.flags |= F_NOTIF_PW_STATUS; 360 nm.fec.type = MAP_TYPE_PWID; 361 nm.fec.fec.pwid.type = pw_type; 362 nm.fec.fec.pwid.group_id = group_id; 363 nm.flags |= F_NOTIF_FEC; 364 365 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0, &nm, 366 sizeof(nm)); 367 } 368 369 void 370 l2vpn_recv_pw_status(struct lde_nbr *ln, struct notify_msg *nm) 371 { 372 struct fec fec; 373 struct fec_node *fn; 374 struct fec_nh *fnh; 375 struct l2vpn_pw *pw; 376 377 if (nm->fec.type == MAP_TYPE_TYPED_WCARD || 378 !(nm->fec.flags & F_MAP_PW_ID)) { 379 l2vpn_recv_pw_status_wcard(ln, nm); 380 return; 381 } 382 383 lde_map2fec(&nm->fec, ln->id, &fec); 384 fn = (struct fec_node *)fec_find(&ft, &fec); 385 if (fn == NULL) 386 /* unknown fec */ 387 return; 388 389 pw = (struct l2vpn_pw *) fn->data; 390 if (pw == NULL) 391 return; 392 393 fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id, 0); 394 if (fnh == NULL) 395 return; 396 397 /* remote status didn't change */ 398 if (pw->remote_status == nm->pw_status) 399 return; 400 pw->remote_status = nm->pw_status; 401 402 if (l2vpn_pw_ok(pw, fnh)) 403 lde_send_change_klabel(fn, fnh); 404 else 405 lde_send_delete_klabel(fn, fnh); 406 } 407 408 /* RFC4447 PWid group wildcard */ 409 void 410 l2vpn_recv_pw_status_wcard(struct lde_nbr *ln, struct notify_msg *nm) 411 { 412 struct fec *f; 413 struct fec_node *fn; 414 struct fec_nh *fnh; 415 struct l2vpn_pw *pw; 416 struct map *wcard = &nm->fec; 417 418 RB_FOREACH(f, fec_tree, &ft) { 419 fn = (struct fec_node *)f; 420 if (fn->fec.type != FEC_TYPE_PWID) 421 continue; 422 423 pw = (struct l2vpn_pw *) fn->data; 424 if (pw == NULL) 425 continue; 426 427 switch (wcard->type) { 428 case MAP_TYPE_TYPED_WCARD: 429 if (wcard->fec.twcard.u.pw_type != PW_TYPE_WILDCARD && 430 wcard->fec.twcard.u.pw_type != fn->fec.u.pwid.type) 431 continue; 432 break; 433 case MAP_TYPE_PWID: 434 if (wcard->fec.pwid.type != fn->fec.u.pwid.type) 435 continue; 436 if (wcard->fec.pwid.group_id != pw->remote_group) 437 continue; 438 break; 439 } 440 441 fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id, 0); 442 if (fnh == NULL) 443 continue; 444 445 /* remote status didn't change */ 446 if (pw->remote_status == nm->pw_status) 447 continue; 448 pw->remote_status = nm->pw_status; 449 450 if (l2vpn_pw_ok(pw, fnh)) 451 lde_send_change_klabel(fn, fnh); 452 else 453 lde_send_delete_klabel(fn, fnh); 454 } 455 } 456 457 void 458 l2vpn_sync_pws(int af, union ldpd_addr *addr) 459 { 460 struct l2vpn *l2vpn; 461 struct l2vpn_pw *pw; 462 struct fec fec; 463 struct fec_node *fn; 464 struct fec_nh *fnh; 465 466 LIST_FOREACH(l2vpn, &ldeconf->l2vpn_list, entry) { 467 LIST_FOREACH(pw, &l2vpn->pw_list, entry) { 468 if (af != pw->af || ldp_addrcmp(af, &pw->addr, addr)) 469 continue; 470 471 l2vpn_pw_fec(pw, &fec); 472 fn = (struct fec_node *)fec_find(&ft, &fec); 473 if (fn == NULL) 474 continue; 475 fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *) 476 &pw->lsr_id, 0); 477 if (fnh == NULL) 478 continue; 479 480 if (l2vpn_pw_ok(pw, fnh)) 481 lde_send_change_klabel(fn, fnh); 482 else 483 lde_send_delete_klabel(fn, fnh); 484 } 485 } 486 } 487 488 void 489 l2vpn_pw_ctl(pid_t pid) 490 { 491 struct l2vpn *l2vpn; 492 struct l2vpn_pw *pw; 493 static struct ctl_pw pwctl; 494 495 LIST_FOREACH(l2vpn, &ldeconf->l2vpn_list, entry) 496 LIST_FOREACH(pw, &l2vpn->pw_list, entry) { 497 memset(&pwctl, 0, sizeof(pwctl)); 498 strlcpy(pwctl.ifname, pw->ifname, 499 sizeof(pwctl.ifname)); 500 pwctl.pwid = pw->pwid; 501 pwctl.lsr_id = pw->lsr_id; 502 pwctl.status = pw->flags & F_PW_STATUS_UP; 503 504 lde_imsg_compose_ldpe(IMSG_CTL_SHOW_L2VPN_PW, 0, 505 pid, &pwctl, sizeof(pwctl)); 506 } 507 } 508 509 void 510 l2vpn_binding_ctl(pid_t pid) 511 { 512 struct fec *f; 513 struct fec_node *fn; 514 struct lde_map *me; 515 struct l2vpn_pw *pw; 516 static struct ctl_pw pwctl; 517 518 RB_FOREACH(f, fec_tree, &ft) { 519 if (f->type != FEC_TYPE_PWID) 520 continue; 521 522 fn = (struct fec_node *)f; 523 if (fn->local_label == NO_LABEL && 524 LIST_EMPTY(&fn->downstream)) 525 continue; 526 527 memset(&pwctl, 0, sizeof(pwctl)); 528 pwctl.type = f->u.pwid.type; 529 pwctl.pwid = f->u.pwid.pwid; 530 pwctl.lsr_id = f->u.pwid.lsr_id; 531 532 pw = (struct l2vpn_pw *) fn->data; 533 if (pw) { 534 pwctl.local_label = fn->local_label; 535 pwctl.local_gid = 0; 536 pwctl.local_ifmtu = pw->l2vpn->mtu; 537 } else 538 pwctl.local_label = NO_LABEL; 539 540 LIST_FOREACH(me, &fn->downstream, entry) 541 if (f->u.pwid.lsr_id.s_addr == me->nexthop->id.s_addr) 542 break; 543 544 if (me) { 545 pwctl.remote_label = me->map.label; 546 pwctl.remote_gid = me->map.fec.pwid.group_id; 547 if (me->map.flags & F_MAP_PW_IFMTU) 548 pwctl.remote_ifmtu = me->map.fec.pwid.ifmtu; 549 550 lde_imsg_compose_ldpe(IMSG_CTL_SHOW_L2VPN_BINDING, 551 0, pid, &pwctl, sizeof(pwctl)); 552 } else if (pw) { 553 pwctl.remote_label = NO_LABEL; 554 555 lde_imsg_compose_ldpe(IMSG_CTL_SHOW_L2VPN_BINDING, 556 0, pid, &pwctl, sizeof(pwctl)); 557 } 558 } 559 } 560 561 /* ldpe */ 562 563 void 564 ldpe_l2vpn_init(struct l2vpn *l2vpn) 565 { 566 struct l2vpn_pw *pw; 567 568 LIST_FOREACH(pw, &l2vpn->pw_list, entry) 569 ldpe_l2vpn_pw_init(pw); 570 } 571 572 void 573 ldpe_l2vpn_exit(struct l2vpn *l2vpn) 574 { 575 struct l2vpn_pw *pw; 576 577 LIST_FOREACH(pw, &l2vpn->pw_list, entry) 578 ldpe_l2vpn_pw_exit(pw); 579 } 580 581 void 582 ldpe_l2vpn_pw_init(struct l2vpn_pw *pw) 583 { 584 struct tnbr *tnbr; 585 586 tnbr = tnbr_find(leconf, pw->af, &pw->addr); 587 if (tnbr == NULL) { 588 tnbr = tnbr_new(leconf, pw->af, &pw->addr); 589 tnbr_update(tnbr); 590 LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry); 591 } 592 593 tnbr->pw_count++; 594 } 595 596 void 597 ldpe_l2vpn_pw_exit(struct l2vpn_pw *pw) 598 { 599 struct tnbr *tnbr; 600 601 tnbr = tnbr_find(leconf, pw->af, &pw->addr); 602 if (tnbr) { 603 tnbr->pw_count--; 604 tnbr_check(tnbr); 605 } 606 } 607