1 /* $OpenBSD: l2vpn.c,v 1.13 2016/05/23 18:55:21 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, pw->lsr_id, 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, pw->lsr_id); 177 } 178 179 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 fec.type = FEC_TYPE_IPV4; 229 fec.u.ipv4.prefix = pw->lsr_id; 230 fec.u.ipv4.prefixlen = 32; 231 fn = (struct fec_node *)fec_find(&ft, &fec); 232 if (fn == NULL || fn->local_label == NO_LABEL) 233 return (0); 234 /* 235 * Need to ensure that there's a label binding for all nexthops. 236 * Otherwise, ECMP for this route could render the pseudowire unusable. 237 */ 238 LIST_FOREACH(fnh, &fn->nexthops, entry) 239 if (fnh->remote_label == NO_LABEL) 240 return (0); 241 242 return (1); 243 } 244 245 int 246 l2vpn_pw_negotiate(struct lde_nbr *ln, struct fec_node *fn, struct map *map) 247 { 248 struct l2vpn_pw *pw; 249 250 /* NOTE: thanks martini & friends for all this mess */ 251 252 pw = (struct l2vpn_pw *) fn->data; 253 if (pw == NULL) 254 /* 255 * pseudowire not configured, return and record 256 * the mapping later 257 */ 258 return (0); 259 260 /* RFC4447 - Section 6.2: control word negotiation */ 261 if (fec_find(&ln->sent_map, &fn->fec)) { 262 if ((map->flags & F_MAP_PW_CWORD) && 263 !(pw->flags & F_PW_CWORD_CONF)) { 264 /* ignore the received label mapping */ 265 return (1); 266 } else if (!(map->flags & F_MAP_PW_CWORD) && 267 (pw->flags & F_PW_CWORD_CONF)) { 268 /* TODO append a "Wrong C-bit" status code */ 269 lde_send_labelwithdraw(ln, fn, NO_LABEL); 270 271 pw->flags &= ~F_PW_CWORD; 272 lde_send_labelmapping(ln, fn, 1); 273 } 274 } else if (map->flags & F_MAP_PW_CWORD) { 275 if (pw->flags & F_PW_CWORD_CONF) 276 pw->flags |= F_PW_CWORD; 277 else 278 /* act as if no label mapping had been received */ 279 return (1); 280 } else 281 pw->flags &= ~F_PW_CWORD; 282 283 /* RFC4447 - Section 5.4.3: pseudowire status negotiation */ 284 if (fec_find(&ln->recv_map, &fn->fec) == NULL && 285 !(map->flags & F_MAP_PW_STATUS)) 286 pw->flags &= ~F_PW_STATUSTLV; 287 288 return (0); 289 } 290 291 void 292 l2vpn_send_pw_status(uint32_t peerid, uint32_t status, struct fec *fec) 293 { 294 struct notify_msg nm; 295 296 memset(&nm, 0, sizeof(nm)); 297 nm.status = S_PW_STATUS; 298 299 nm.pw_status = status; 300 nm.flags |= F_NOTIF_PW_STATUS; 301 302 lde_fec2map(fec, &nm.fec); 303 nm.flags |= F_NOTIF_FEC; 304 305 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, peerid, 0, 306 &nm, sizeof(nm)); 307 } 308 309 void 310 l2vpn_recv_pw_status(struct lde_nbr *ln, struct notify_msg *nm) 311 { 312 struct fec fec; 313 struct fec_node *fn; 314 struct fec_nh *fnh; 315 struct l2vpn_pw *pw; 316 317 /* TODO group wildcard */ 318 if (!(nm->fec.flags & F_MAP_PW_ID)) 319 return; 320 321 lde_map2fec(&nm->fec, ln->id, &fec); 322 fn = (struct fec_node *)fec_find(&ft, &fec); 323 if (fn == NULL) 324 /* unknown fec */ 325 return; 326 327 pw = (struct l2vpn_pw *) fn->data; 328 if (pw == NULL) 329 return; 330 331 fnh = fec_nh_find(fn, ln->id); 332 if (fnh == NULL) 333 return; 334 335 /* remote status didn't change */ 336 if (pw->remote_status == nm->pw_status) 337 return; 338 339 pw->remote_status = nm->pw_status; 340 341 if (l2vpn_pw_ok(pw, fnh)) 342 lde_send_change_klabel(fn, fnh); 343 else 344 lde_send_delete_klabel(fn, fnh); 345 } 346 347 void 348 l2vpn_sync_pws(struct in_addr addr) 349 { 350 struct l2vpn *l2vpn; 351 struct l2vpn_pw *pw; 352 struct fec fec; 353 struct fec_node *fn; 354 struct fec_nh *fnh; 355 356 LIST_FOREACH(l2vpn, &ldeconf->l2vpn_list, entry) { 357 LIST_FOREACH(pw, &l2vpn->pw_list, entry) { 358 if (pw->lsr_id.s_addr != addr.s_addr) 359 continue; 360 361 l2vpn_pw_fec(pw, &fec); 362 fn = (struct fec_node *)fec_find(&ft, &fec); 363 if (fn == NULL) 364 continue; 365 fnh = fec_nh_find(fn, pw->lsr_id); 366 if (fnh == NULL) 367 continue; 368 369 if (l2vpn_pw_ok(pw, fnh)) 370 lde_send_change_klabel(fn, fnh); 371 else 372 lde_send_delete_klabel(fn, fnh); 373 } 374 } 375 } 376 377 void 378 l2vpn_pw_ctl(pid_t pid) 379 { 380 struct l2vpn *l2vpn; 381 struct l2vpn_pw *pw; 382 static struct ctl_pw pwctl; 383 384 LIST_FOREACH(l2vpn, &ldeconf->l2vpn_list, entry) 385 LIST_FOREACH(pw, &l2vpn->pw_list, entry) { 386 memset(&pwctl, 0, sizeof(pwctl)); 387 strlcpy(pwctl.ifname, pw->ifname, 388 sizeof(pwctl.ifname)); 389 pwctl.pwid = pw->pwid; 390 pwctl.lsr_id = pw->lsr_id; 391 pwctl.status = pw->flags & F_PW_STATUS_UP; 392 393 lde_imsg_compose_ldpe(IMSG_CTL_SHOW_L2VPN_PW, 0, 394 pid, &pwctl, sizeof(pwctl)); 395 } 396 } 397 398 void 399 l2vpn_binding_ctl(pid_t pid) 400 { 401 struct fec *f; 402 struct fec_node *fn; 403 struct lde_map *me; 404 struct l2vpn_pw *pw; 405 static struct ctl_pw pwctl; 406 407 RB_FOREACH(f, fec_tree, &ft) { 408 if (f->type != FEC_TYPE_PWID) 409 continue; 410 411 fn = (struct fec_node *)f; 412 if (fn->local_label == NO_LABEL && 413 LIST_EMPTY(&fn->downstream)) 414 continue; 415 416 memset(&pwctl, 0, sizeof(pwctl)); 417 pwctl.type = f->u.pwid.type; 418 pwctl.pwid = f->u.pwid.pwid; 419 pwctl.lsr_id = f->u.pwid.lsr_id; 420 421 pw = (struct l2vpn_pw *) fn->data; 422 if (pw) { 423 pwctl.local_label = fn->local_label; 424 pwctl.local_gid = 0; 425 pwctl.local_ifmtu = pw->l2vpn->mtu; 426 } else 427 pwctl.local_label = NO_LABEL; 428 429 LIST_FOREACH(me, &fn->downstream, entry) 430 if (f->u.pwid.lsr_id.s_addr == me->nexthop->id.s_addr) 431 break; 432 433 if (me) { 434 pwctl.remote_label = me->map.label; 435 pwctl.remote_gid = me->map.fec.pwid.group_id; 436 if (me->map.flags & F_MAP_PW_IFMTU) 437 pwctl.remote_ifmtu = me->map.fec.pwid.ifmtu; 438 439 lde_imsg_compose_ldpe(IMSG_CTL_SHOW_L2VPN_BINDING, 440 0, pid, &pwctl, sizeof(pwctl)); 441 } else if (pw) { 442 pwctl.remote_label = NO_LABEL; 443 444 lde_imsg_compose_ldpe(IMSG_CTL_SHOW_L2VPN_BINDING, 445 0, pid, &pwctl, sizeof(pwctl)); 446 } 447 } 448 } 449 450 /* ldpe */ 451 452 void 453 ldpe_l2vpn_init(struct l2vpn *l2vpn) 454 { 455 struct l2vpn_pw *pw; 456 457 LIST_FOREACH(pw, &l2vpn->pw_list, entry) 458 ldpe_l2vpn_pw_init(pw); 459 } 460 461 void 462 ldpe_l2vpn_exit(struct l2vpn *l2vpn) 463 { 464 struct l2vpn_pw *pw; 465 466 LIST_FOREACH(pw, &l2vpn->pw_list, entry) 467 ldpe_l2vpn_pw_exit(pw); 468 } 469 470 void 471 ldpe_l2vpn_pw_init(struct l2vpn_pw *pw) 472 { 473 struct tnbr *tnbr; 474 475 tnbr = tnbr_find(leconf, pw->lsr_id); 476 if (tnbr == NULL) { 477 tnbr = tnbr_new(leconf, pw->lsr_id); 478 tnbr_update(tnbr); 479 LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry); 480 } 481 482 tnbr->pw_count++; 483 } 484 485 void 486 ldpe_l2vpn_pw_exit(struct l2vpn_pw *pw) 487 { 488 struct tnbr *tnbr; 489 490 tnbr = tnbr_find(leconf, pw->lsr_id); 491 if (tnbr) { 492 tnbr->pw_count--; 493 tnbr_check(tnbr); 494 } 495 } 496