diff options
| -rw-r--r-- | doc/Building_FRR_on_OpenBSD6.md | 19 | ||||
| -rw-r--r-- | doc/Building_FRR_on_Ubuntu1204.md | 1 | ||||
| -rw-r--r-- | doc/Building_FRR_on_Ubuntu1604.md | 1 | ||||
| -rw-r--r-- | ldpd/lde.c | 2 | ||||
| -rw-r--r-- | ldpd/ldp_vty_exec.c | 29 | ||||
| -rw-r--r-- | zebra/zebra_mpls_openbsd.c | 139 |
6 files changed, 155 insertions, 36 deletions
diff --git a/doc/Building_FRR_on_OpenBSD6.md b/doc/Building_FRR_on_OpenBSD6.md index 9e13d5ce45..8ec23854a6 100644 --- a/doc/Building_FRR_on_OpenBSD6.md +++ b/doc/Building_FRR_on_OpenBSD6.md @@ -1,12 +1,6 @@ Building FRR on OpenBSD 6 from Git Source ========================================= -OpenBSD restrictions: ---------------------- - -- MPLS is not tested on `OpenBSD`. It may work as it shares the - sources with the LDPd on OpenBSD. Bug reports and fixes are welcome - Install required packages ------------------------- @@ -61,7 +55,6 @@ an example) --enable-rtadv \ --enable-tcp-zebra \ --enable-fpm \ - --enable-ldpd \ --with-pkg-git-version \ --with-pkg-extra-version=-MyOwnFRRVersion gmake @@ -99,6 +92,18 @@ Add the following lines to the end of `/etc/rc.conf`: **Reboot** to apply the config to the system +### Enable MPLS Forwarding + +To enable MPLS forwarding on a given interface, use the following command: + + sudo ifconfig em0 mpls + +Alternatively, to make MPLS forwarding persistent across reboots, add the "mpls" +keyword in the hostname.* files of the desired interfaces. Example: + + cat /etc/hostname.em0 + inet 10.0.1.1 255.255.255.0 mpls + ### Install rc.d init files (create them in /etc/rc.d - no example are included at this time with FRR source) diff --git a/doc/Building_FRR_on_Ubuntu1204.md b/doc/Building_FRR_on_Ubuntu1204.md index 3312a2c9c8..0e8fe6d8f4 100644 --- a/doc/Building_FRR_on_Ubuntu1204.md +++ b/doc/Building_FRR_on_Ubuntu1204.md @@ -94,7 +94,6 @@ an example.) --enable-rtadv \ --enable-tcp-zebra \ --enable-fpm \ - --enable-ldpd \ --with-pkg-git-version \ --with-pkg-extra-version=-MyOwnFRRVersion make diff --git a/doc/Building_FRR_on_Ubuntu1604.md b/doc/Building_FRR_on_Ubuntu1604.md index d1e1a377d0..17cc4949bd 100644 --- a/doc/Building_FRR_on_Ubuntu1604.md +++ b/doc/Building_FRR_on_Ubuntu1604.md @@ -55,7 +55,6 @@ an example.) --enable-rtadv \ --enable-tcp-zebra \ --enable-fpm \ - --enable-ldpd \ --with-pkg-git-version \ --with-pkg-extra-version=-MyOwnFRRVersion make diff --git a/ldpd/lde.c b/ldpd/lde.c index e927e45367..53fde32fd9 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -170,7 +170,7 @@ lde(const char *user, const char *group, u_short instance) zprivs_init(&lde_privs); #ifdef HAVE_PLEDGE - if (pledge("stdio recvfd", NULL) == -1) + if (pledge("stdio recvfd unix", NULL) == -1) fatal("pledge"); #endif diff --git a/ldpd/ldp_vty_exec.c b/ldpd/ldp_vty_exec.c index 616847b363..dfd5af9748 100644 --- a/ldpd/ldp_vty_exec.c +++ b/ldpd/ldp_vty_exec.c @@ -213,10 +213,10 @@ show_discovery_msg(struct vty *vty, struct imsg *imsg, vty_out(vty, "%-8s %-15s ", "Targeted", addr); if (strlen(addr) > 15) - vty_out(vty, "\n%46s", " "); + vty_out(vty, "%s%46s", VTY_NEWLINE, " "); break; } - vty_out(vty, "%9u\n", adj->holdtime); + vty_out(vty, "%9u%s", adj->holdtime, VTY_NEWLINE); break; case IMSG_CTL_END: vty_out(vty, "%s", VTY_NEWLINE); @@ -516,9 +516,9 @@ show_nbr_msg(struct vty *vty, struct imsg *imsg, struct show_params *params) af_name(nbr->af), inet_ntoa(nbr->id), nbr_state_name(nbr->nbr_state), addr); if (strlen(addr) > 15) - vty_out(vty, "\n%48s", " "); - vty_out(vty, " %8s\n", nbr->uptime == 0 ? "-" : - log_time(nbr->uptime)); + vty_out(vty, "%s%48s", VTY_NEWLINE, " "); + vty_out(vty, " %8s%s", nbr->uptime == 0 ? "-" : + log_time(nbr->uptime), VTY_NEWLINE); break; case IMSG_CTL_END: return (1); @@ -1031,10 +1031,10 @@ show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params) vty_out(vty, "%-4s %-20s", af_name(rt->af), dstnet); if (strlen(dstnet) > 20) - vty_out(vty, "\n%25s", " "); - vty_out(vty, " %-15s %-11s %-13s %6s\n", inet_ntoa(rt->nexthop), + vty_out(vty, "%s%25s", VTY_NEWLINE, " "); + vty_out(vty, " %-15s %-11s %-13s %6s%s", inet_ntoa(rt->nexthop), log_label(rt->local_label), log_label(rt->remote_label), - rt->in_use ? "yes" : "no"); + rt->in_use ? "yes" : "no", VTY_NEWLINE); break; case IMSG_CTL_END: vty_out(vty, "%s", VTY_NEWLINE); @@ -1603,9 +1603,9 @@ ldp_vty_show_binding(struct vty *vty, struct vty_arg *args[]) params.json = vty_get_arg_value(args, "json") ? 1 : 0; if (!params.detail && !params.json) - vty_out(vty, "%-4s %-20s %-15s %-11s %-13s %6s\n", "AF", + vty_out(vty, "%-4s %-20s %-15s %-11s %-13s %6s%s", "AF", "Destination", "Nexthop", "Local Label", "Remote Label", - "In Use"); + "In Use", VTY_NEWLINE); imsg_compose(&ibuf, IMSG_CTL_SHOW_LIB, 0, 0, -1, NULL, 0); return (ldp_vty_dispatch(vty, &ibuf, SHOW_LIB, ¶ms)); @@ -1632,8 +1632,8 @@ ldp_vty_show_discovery(struct vty *vty, struct vty_arg *args[]) params.json = vty_get_arg_value(args, "json") ? 1 : 0; if (!params.detail && !params.json) - vty_out(vty, "%-4s %-15s %-8s %-15s %9s\n", - "AF", "ID", "Type", "Source", "Holdtime"); + vty_out(vty, "%-4s %-15s %-8s %-15s %9s%s", + "AF", "ID", "Type", "Source", "Holdtime", VTY_NEWLINE); if (params.detail) imsg_compose(&ibuf, IMSG_CTL_SHOW_DISCOVERY_DTL, 0, 0, -1, @@ -1745,8 +1745,9 @@ ldp_vty_show_neighbor(struct vty *vty, struct vty_arg *args[]) params.detail = 1; if (!params.detail && !params.json) - vty_out(vty, "%-4s %-15s %-11s %-15s %8s\n", - "AF", "ID", "State", "Remote Address", "Uptime"); + vty_out(vty, "%-4s %-15s %-11s %-15s %8s%s", + "AF", "ID", "State", "Remote Address", "Uptime", + VTY_NEWLINE); imsg_compose(&ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); return (ldp_vty_dispatch(vty, &ibuf, SHOW_NBR, ¶ms)); diff --git a/zebra/zebra_mpls_openbsd.c b/zebra/zebra_mpls_openbsd.c index b68b03e0c4..eaa80ac558 100644 --- a/zebra/zebra_mpls_openbsd.c +++ b/zebra/zebra_mpls_openbsd.c @@ -38,7 +38,7 @@ struct { } kr_state; static int -kernel_send_rtmsg (int action, mpls_label_t in_label, zebra_nhlfe_t *nhlfe) +kernel_send_rtmsg_v4 (int action, mpls_label_t in_label, zebra_nhlfe_t *nhlfe) { struct iovec iov[5]; struct rt_msghdr hdr; @@ -48,10 +48,10 @@ kernel_send_rtmsg (int action, mpls_label_t in_label, zebra_nhlfe_t *nhlfe) int ret; if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug ("kernel_send_rtmsg: 0x%x, label=%u", action, in_label); + zlog_debug ("%s: 0x%x, label=%u", __func__, action, in_label); /* initialize header */ - bzero(&hdr, sizeof (hdr)); + memset (&hdr, 0, sizeof (hdr)); hdr.rtm_version = RTM_VERSION; hdr.rtm_type = action; @@ -66,7 +66,7 @@ kernel_send_rtmsg (int action, mpls_label_t in_label, zebra_nhlfe_t *nhlfe) iov[iovcnt++].iov_len = sizeof (hdr); /* in label */ - bzero(&sa_label_in, sizeof (sa_label_in)); + memset (&sa_label_in, 0, sizeof (sa_label_in)); sa_label_in.smpls_len = sizeof (sa_label_in); sa_label_in.smpls_family = AF_MPLS; sa_label_in.smpls_label = htonl(in_label << MPLS_LABEL_OFFSET); @@ -79,7 +79,7 @@ kernel_send_rtmsg (int action, mpls_label_t in_label, zebra_nhlfe_t *nhlfe) iov[iovcnt++].iov_len = sizeof (sa_label_in); /* nexthop */ - bzero(&nexthop, sizeof (nexthop)); + memset (&nexthop, 0, sizeof (nexthop)); nexthop.sin_len = sizeof (nexthop); nexthop.sin_family = AF_INET; nexthop.sin_addr = nhlfe->nexthop->gate.ipv4; @@ -94,7 +94,7 @@ kernel_send_rtmsg (int action, mpls_label_t in_label, zebra_nhlfe_t *nhlfe) /* If action is RTM_DELETE we have to get rid of MPLS infos */ if (action != RTM_DELETE) { - bzero(&sa_label_out, sizeof (sa_label_out)); + memset (&sa_label_out, 0, sizeof (sa_label_out)); sa_label_out.smpls_len = sizeof (sa_label_out); sa_label_out.smpls_family = AF_MPLS; sa_label_out.smpls_label = @@ -120,7 +120,116 @@ kernel_send_rtmsg (int action, mpls_label_t in_label, zebra_nhlfe_t *nhlfe) zlog_err ("Can't lower privileges"); if (ret == -1) - zlog_err ("kernel_send_rtmsg: %s", safe_strerror (errno)); + zlog_err ("%s: %s", __func__, safe_strerror (errno)); + + return ret; +} + +#if !defined(ROUNDUP) +#define ROUNDUP(a) \ + (((a) & (sizeof(long) - 1)) ? (1 + ((a) | (sizeof(long) - 1))) : (a)) +#endif + +static int +kernel_send_rtmsg_v6 (int action, mpls_label_t in_label, zebra_nhlfe_t *nhlfe) +{ + struct iovec iov[5]; + struct rt_msghdr hdr; + struct sockaddr_mpls sa_label_in, sa_label_out; + struct pad { + struct sockaddr_in6 addr; + char pad[sizeof(long)]; /* thank you IPv6 */ + } nexthop; + int iovcnt = 0; + int ret; + + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug ("%s: 0x%x, label=%u", __func__, action, in_label); + + /* initialize header */ + memset (&hdr, 0, sizeof (hdr)); + hdr.rtm_version = RTM_VERSION; + + hdr.rtm_type = action; + hdr.rtm_flags = RTF_UP; + hdr.rtm_fmask = RTF_MPLS; + hdr.rtm_seq = kr_state.rtseq++; /* overflow doesn't matter */ + hdr.rtm_msglen = sizeof (hdr); + hdr.rtm_hdrlen = sizeof (struct rt_msghdr); + hdr.rtm_priority = 0; + /* adjust iovec */ + iov[iovcnt].iov_base = &hdr; + iov[iovcnt++].iov_len = sizeof (hdr); + + /* in label */ + memset (&sa_label_in, 0, sizeof (sa_label_in)); + sa_label_in.smpls_len = sizeof (sa_label_in); + sa_label_in.smpls_family = AF_MPLS; + sa_label_in.smpls_label = htonl(in_label << MPLS_LABEL_OFFSET); + /* adjust header */ + hdr.rtm_flags |= RTF_MPLS | RTF_MPATH; + hdr.rtm_addrs |= RTA_DST; + hdr.rtm_msglen += sizeof (sa_label_in); + /* adjust iovec */ + iov[iovcnt].iov_base = &sa_label_in; + iov[iovcnt++].iov_len = sizeof (sa_label_in); + + /* nexthop */ + memset (&nexthop, 0, sizeof (nexthop)); + nexthop.addr.sin6_len = sizeof (struct sockaddr_in6); + nexthop.addr.sin6_family = AF_INET6; + nexthop.addr.sin6_addr = nhlfe->nexthop->gate.ipv6; + if (IN6_IS_ADDR_LINKLOCAL (&nexthop.addr.sin6_addr)) + { + uint16_t tmp16; + struct sockaddr_in6 *sin6 = &nexthop.addr; + + nexthop.addr.sin6_scope_id = nhlfe->nexthop->ifindex; + + memcpy (&tmp16, &sin6->sin6_addr.s6_addr[2], sizeof (tmp16)); + tmp16 = htons (sin6->sin6_scope_id); + memcpy (&sin6->sin6_addr.s6_addr[2], &tmp16, sizeof (tmp16)); + sin6->sin6_scope_id = 0; + } + + /* adjust header */ + hdr.rtm_flags |= RTF_GATEWAY; + hdr.rtm_addrs |= RTA_GATEWAY; + hdr.rtm_msglen += ROUNDUP (sizeof (struct sockaddr_in6)); + /* adjust iovec */ + iov[iovcnt].iov_base = &nexthop; + iov[iovcnt++].iov_len = ROUNDUP (sizeof (struct sockaddr_in6)); + + /* If action is RTM_DELETE we have to get rid of MPLS infos */ + if (action != RTM_DELETE) + { + memset (&sa_label_out, 0, sizeof (sa_label_out)); + sa_label_out.smpls_len = sizeof (sa_label_out); + sa_label_out.smpls_family = AF_MPLS; + sa_label_out.smpls_label = + htonl(nhlfe->nexthop->nh_label->label[0] << MPLS_LABEL_OFFSET); + /* adjust header */ + hdr.rtm_addrs |= RTA_SRC; + hdr.rtm_flags |= RTF_MPLS; + hdr.rtm_msglen += sizeof (sa_label_out); + /* adjust iovec */ + iov[iovcnt].iov_base = &sa_label_out; + iov[iovcnt++].iov_len = sizeof (sa_label_out); + + if (nhlfe->nexthop->nh_label->label[0] == MPLS_LABEL_IMPLNULL) + hdr.rtm_mpls = MPLS_OP_POP; + else + hdr.rtm_mpls = MPLS_OP_SWAP; + } + + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog_err ("Can't raise privileges"); + ret = writev (kr_state.fd, iov, iovcnt); + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog_err ("Can't lower privileges"); + + if (ret == -1) + zlog_err ("%s: %s", __func__, safe_strerror (errno)); return ret; } @@ -141,10 +250,6 @@ kernel_lsp_cmd (int action, zebra_lsp_t *lsp) if (nexthop_num >= multipath_num) break; - /* XXX */ - if (NHLFE_FAMILY(nhlfe) == AF_INET6) - continue; - if (((action == RTM_ADD || action == RTM_CHANGE) && (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED) && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))) || @@ -154,7 +259,17 @@ kernel_lsp_cmd (int action, zebra_lsp_t *lsp) { nexthop_num++; - kernel_send_rtmsg (action, lsp->ile.in_label, nhlfe); + switch (NHLFE_FAMILY(nhlfe)) + { + case AF_INET: + kernel_send_rtmsg_v4 (action, lsp->ile.in_label, nhlfe); + break; + case AF_INET6: + kernel_send_rtmsg_v6 (action, lsp->ile.in_label, nhlfe); + break; + default: + break; + } if (action == RTM_ADD || action == RTM_CHANGE) { SET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED); |
