mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 20:51:17 +00:00
Merge pull request #297 from opensourcerouting/ldpd-openbsd
Add support for MPLSv6 in OpenBSD + minor fixes
This commit is contained in:
commit
821260f642
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user