2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2002-12-13 21:15:29 +01:00
|
|
|
/*
|
|
|
|
* Common ioctl functions.
|
|
|
|
* Copyright (C) 1997, 98 Kunihiro Ishiguro
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
2024-01-04 20:42:17 +01:00
|
|
|
#include <sys/ioctl.h>
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "linklist.h"
|
|
|
|
#include "if.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "ioctl.h"
|
|
|
|
#include "log.h"
|
2003-06-04 15:59:38 +02:00
|
|
|
#include "privs.h"
|
2018-06-14 16:38:40 +02:00
|
|
|
#include "lib_errors.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-10-06 22:23:13 +02:00
|
|
|
#include "vty.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "zebra/rib.h"
|
|
|
|
#include "zebra/rt.h"
|
[zebra/solaris] Interface state fixups for Solaris.
2006-01-25 Paul Jakma <paul.jakma@sun.com>
* (general) More solaris PF_ROUTE hacks. The IFF_UP mangling
for solaris was incomplete on the PF_ROUTE side. fix it.
This changeset generally uglifies things. For some future
work I'd like to see the state changes seperated out from
the details of the code. Differences between systems might
then be slightly easier to implement without convoluted
hacks.
Changes should be specific to Solaris mostly, however
also tested on FreeBSD 6.
* if_ioctl_solaris.c: (interface_list_ioctl) ignore ~IFF_UP
interfaces, we'll hear about them when/if interface goes up
through NEWADDR.
Update flags explicitely at end of it to kick mangling.
* ioctl_solaris.c: (if_mangle_up) removed to interface.c, in
kind.
(lifreq_set_name) more convenient to take the string, than
the ifp.
(if_get_flags_direct) new convenience function, returns
the actual flags. Used during bootstrap in if_ioctl_solaris.c
to peek at flags of logical interfaces to see whether or
not to ignore them.
(if_get_flags) ENXIO means it's gone, poke out IFF_UP and
kick flags update.
(if_{un,}set_flags) flags argument should be 64bit.
* ioctl.{c,h}: flags argument should be 64bit.
* interface.h: Add a 'primary_state' flag to struct zebra_if on
SUNOS_5.
Export if_flags_update.
* interface.c: (if_flags_mangle) moved over in kind from
ioctl_solaris.c. Nasty kludge to try get IFF_UP right, as
much as is possible. Also keep track of the actual IFF_UP
value for the primary interface, so we can know when the ifp
must be deleted.
(if_flags_update) Take a new interface flags value, apply it
to the interface, and take whatever actions are required due
to flag transitions.
(if_refresh) flag state change logic is moved out to
previous. Just call if_get_flags, which will end up using
previous to effect the update of flags.
(if_flag_dump_vty) IFF_IPV{4,6} aren't interesting, VIRTUAL
and NOXMIT are though.
* kernel_socket.c: (ifm_read) Down->Down transitions shouldn't
create ifp, for non-IFANNOUNCE systems.
Use if_flags_update to update flags.
flag transition logic is now handled automatically through
if_flags_update.
(ifam_read) Better to call if_refresh *after* adding
connected addresses, as connected count affects IFF_UP on
IFF_UP-mangled systems.
On Solaris, Up->Down due to DELADDR means we need to delete
the ifp - the IFINFO might already have been and gone.
* rt.h: include other dependent headers.
2006-01-25 05:31:40 +01:00
|
|
|
#include "zebra/interface.h"
|
2018-08-24 19:14:09 +02:00
|
|
|
#include "zebra/zebra_errors.h"
|
2019-01-25 17:31:51 +01:00
|
|
|
#include "zebra/debug.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2008-01-11 16:57:13 +01:00
|
|
|
#ifdef HAVE_BSD_LINK_DETECT
|
|
|
|
#include <net/if_media.h>
|
|
|
|
#endif /* HAVE_BSD_LINK_DETECT*/
|
|
|
|
|
2003-06-04 15:59:38 +02:00
|
|
|
extern struct zebra_privs_t zserv_privs;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* clear and set interface name string */
|
|
|
|
void ifreq_set_name(struct ifreq *ifreq, struct interface *ifp)
|
|
|
|
{
|
2017-08-25 02:43:29 +02:00
|
|
|
strlcpy(ifreq->ifr_name, ifp->name, sizeof(ifreq->ifr_name));
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2022-05-13 21:58:33 +02:00
|
|
|
#ifndef HAVE_NETLINK
|
2002-12-13 21:15:29 +01:00
|
|
|
/* call ioctl system call */
|
2018-03-27 21:13:34 +02:00
|
|
|
int if_ioctl(unsigned long request, caddr_t buffer)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int sock;
|
2005-01-29 18:07:40 +01:00
|
|
|
int ret;
|
2015-04-21 10:13:07 +02:00
|
|
|
int err = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-08-13 15:47:23 +02:00
|
|
|
frr_with_privs(&zserv_privs) {
|
2018-08-10 18:36:43 +02:00
|
|
|
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
|
if (sock < 0) {
|
|
|
|
zlog_err("Cannot create UDP socket: %s",
|
|
|
|
safe_strerror(errno));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if ((ret = ioctl(sock, request, buffer)) < 0)
|
|
|
|
err = errno;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
close(sock);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret < 0) {
|
|
|
|
errno = err;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2022-05-13 21:58:33 +02:00
|
|
|
#endif
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2018-02-22 19:10:32 +01:00
|
|
|
/* call ioctl system call */
|
2018-03-27 21:13:34 +02:00
|
|
|
int vrf_if_ioctl(unsigned long request, caddr_t buffer, vrf_id_t vrf_id)
|
2018-02-22 19:10:32 +01:00
|
|
|
{
|
|
|
|
int sock;
|
|
|
|
int ret;
|
|
|
|
int err = 0;
|
|
|
|
|
2019-08-13 15:47:23 +02:00
|
|
|
frr_with_privs(&zserv_privs) {
|
2018-08-10 18:36:43 +02:00
|
|
|
sock = vrf_socket(AF_INET, SOCK_DGRAM, 0, vrf_id, NULL);
|
|
|
|
if (sock < 0) {
|
|
|
|
zlog_err("Cannot create UDP socket: %s",
|
|
|
|
safe_strerror(errno));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
ret = vrf_ioctl(vrf_id, sock, request, buffer);
|
|
|
|
if (ret < 0)
|
|
|
|
err = errno;
|
2018-02-22 19:10:32 +01:00
|
|
|
}
|
|
|
|
close(sock);
|
|
|
|
|
|
|
|
if (ret < 0) {
|
|
|
|
errno = err;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-12-11 15:21:04 +01:00
|
|
|
#ifndef HAVE_NETLINK
|
2018-03-27 21:13:34 +02:00
|
|
|
static int if_ioctl_ipv6(unsigned long request, caddr_t buffer)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int sock;
|
2005-01-29 18:07:40 +01:00
|
|
|
int ret;
|
2015-04-21 10:13:07 +02:00
|
|
|
int err = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-08-13 15:47:23 +02:00
|
|
|
frr_with_privs(&zserv_privs) {
|
2018-08-10 18:36:43 +02:00
|
|
|
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
|
|
|
if (sock < 0) {
|
|
|
|
zlog_err("Cannot create IPv6 datagram socket: %s",
|
|
|
|
safe_strerror(errno));
|
|
|
|
exit(1);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-08-10 18:36:43 +02:00
|
|
|
if ((ret = ioctl(sock, request, buffer)) < 0)
|
|
|
|
err = errno;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
close(sock);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret < 0) {
|
|
|
|
errno = err;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* get interface metric
|
|
|
|
* -- if value is not avaliable set -1
|
|
|
|
*/
|
|
|
|
void if_get_metric(struct interface *ifp)
|
|
|
|
{
|
|
|
|
#ifdef SIOCGIFMETRIC
|
2022-03-24 17:57:01 +01:00
|
|
|
struct ifreq ifreq = {};
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
ifreq_set_name(&ifreq, ifp);
|
|
|
|
|
2021-10-22 00:17:40 +02:00
|
|
|
if (vrf_if_ioctl(SIOCGIFMETRIC, (caddr_t)&ifreq, ifp->vrf->vrf_id) < 0)
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
ifp->metric = ifreq.ifr_metric;
|
|
|
|
if (ifp->metric == 0)
|
|
|
|
ifp->metric = 1;
|
|
|
|
#else /* SIOCGIFMETRIC */
|
|
|
|
ifp->metric = -1;
|
|
|
|
#endif /* SIOCGIFMETRIC */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get interface MTU */
|
|
|
|
void if_get_mtu(struct interface *ifp)
|
|
|
|
{
|
2022-03-24 17:57:01 +01:00
|
|
|
struct ifreq ifreq = {};
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
ifreq_set_name(&ifreq, ifp);
|
|
|
|
|
|
|
|
#if defined(SIOCGIFMTU)
|
2021-10-22 00:17:40 +02:00
|
|
|
if (vrf_if_ioctl(SIOCGIFMTU, (caddr_t)&ifreq, ifp->vrf->vrf_id) < 0) {
|
2022-06-15 13:31:53 +02:00
|
|
|
zlog_info("Can't lookup mtu by ioctl(SIOCGIFMTU) for %s(%u)",
|
|
|
|
ifp->name, ifp->vrf->vrf_id);
|
2004-05-09 13:00:23 +02:00
|
|
|
ifp->mtu6 = ifp->mtu = -1;
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-05-09 13:00:23 +02:00
|
|
|
ifp->mtu6 = ifp->mtu = ifreq.ifr_mtu;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2007-04-10 21:43:43 +02:00
|
|
|
/* propogate */
|
|
|
|
zebra_interface_up_update(ifp);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
#else
|
2022-06-15 13:31:53 +02:00
|
|
|
zlog_info("Can't lookup mtu on this system for %s(%u)", ifp->name,
|
|
|
|
ifp->vrf->vrf_id);
|
2004-05-09 13:00:23 +02:00
|
|
|
ifp->mtu6 = ifp->mtu = -1;
|
2002-12-13 21:15:29 +01:00
|
|
|
#endif
|
|
|
|
}
|
2022-05-13 21:58:33 +02:00
|
|
|
#endif /* ! HAVE_NETLINK */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-01-16 19:40:31 +01:00
|
|
|
/*
|
2019-01-25 17:31:51 +01:00
|
|
|
* Handler for interface address programming via the zebra dplane,
|
|
|
|
* for non-netlink platforms. This handler dispatches to per-platform
|
|
|
|
* helpers, based on the operation requested.
|
2019-01-16 19:40:31 +01:00
|
|
|
*/
|
|
|
|
#ifndef HAVE_NETLINK
|
|
|
|
|
2019-01-25 17:31:51 +01:00
|
|
|
/* Prototypes: these are placed in this block so that they're only seen
|
|
|
|
* on non-netlink platforms.
|
|
|
|
*/
|
|
|
|
static int if_set_prefix_ctx(const struct zebra_dplane_ctx *ctx);
|
|
|
|
static int if_unset_prefix_ctx(const struct zebra_dplane_ctx *ctx);
|
|
|
|
static int if_set_prefix6_ctx(const struct zebra_dplane_ctx *ctx);
|
|
|
|
static int if_unset_prefix6_ctx(const struct zebra_dplane_ctx *ctx);
|
|
|
|
|
2019-01-16 19:40:31 +01:00
|
|
|
enum zebra_dplane_result kernel_address_update_ctx(
|
|
|
|
struct zebra_dplane_ctx *ctx)
|
|
|
|
{
|
2019-01-25 17:31:51 +01:00
|
|
|
int ret = -1;
|
|
|
|
const struct prefix *p;
|
|
|
|
|
|
|
|
p = dplane_ctx_get_intf_addr(ctx);
|
|
|
|
|
|
|
|
if (dplane_ctx_get_op(ctx) == DPLANE_OP_ADDR_INSTALL) {
|
|
|
|
if (p->family == AF_INET)
|
|
|
|
ret = if_set_prefix_ctx(ctx);
|
|
|
|
else
|
|
|
|
ret = if_set_prefix6_ctx(ctx);
|
|
|
|
} else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ADDR_UNINSTALL) {
|
|
|
|
if (p->family == AF_INET)
|
|
|
|
ret = if_unset_prefix_ctx(ctx);
|
|
|
|
else
|
|
|
|
ret = if_unset_prefix6_ctx(ctx);
|
|
|
|
} else {
|
|
|
|
if (IS_ZEBRA_DEBUG_DPLANE)
|
|
|
|
zlog_debug("Invalid op in interface-addr install");
|
|
|
|
}
|
|
|
|
|
|
|
|
return (ret == 0 ?
|
|
|
|
ZEBRA_DPLANE_REQUEST_SUCCESS : ZEBRA_DPLANE_REQUEST_FAILURE);
|
2019-01-16 19:40:31 +01:00
|
|
|
}
|
|
|
|
|
2019-01-25 17:31:51 +01:00
|
|
|
#ifdef HAVE_STRUCT_IFALIASREQ
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Helper for interface-addr install, non-netlink
|
|
|
|
*/
|
|
|
|
static int if_set_prefix_ctx(const struct zebra_dplane_ctx *ctx)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2019-01-25 17:31:51 +01:00
|
|
|
int ret;
|
|
|
|
struct ifaliasreq addreq;
|
|
|
|
struct sockaddr_in addr, mask, peer;
|
|
|
|
struct prefix_ipv4 *p;
|
|
|
|
|
|
|
|
p = (struct prefix_ipv4 *)dplane_ctx_get_intf_addr(ctx);
|
|
|
|
|
|
|
|
memset(&addreq, 0, sizeof(addreq));
|
2019-05-08 20:33:53 +02:00
|
|
|
strlcpy((char *)&addreq.ifra_name, dplane_ctx_get_ifname(ctx),
|
2019-01-25 17:31:51 +01:00
|
|
|
sizeof(addreq.ifra_name));
|
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&addr, 0, sizeof(addr));
|
2019-01-25 17:31:51 +01:00
|
|
|
addr.sin_addr = p->prefix;
|
|
|
|
addr.sin_family = p->family;
|
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
|
|
|
addr.sin_len = sizeof(struct sockaddr_in);
|
|
|
|
#endif
|
|
|
|
memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
if (dplane_ctx_intf_is_connected(ctx)) {
|
|
|
|
p = (struct prefix_ipv4 *)dplane_ctx_get_intf_dest(ctx);
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&mask, 0, sizeof(mask));
|
2019-01-25 17:31:51 +01:00
|
|
|
peer.sin_addr = p->prefix;
|
|
|
|
peer.sin_family = p->family;
|
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
|
|
|
peer.sin_len = sizeof(struct sockaddr_in);
|
|
|
|
#endif
|
|
|
|
memcpy(&addreq.ifra_broadaddr, &peer,
|
|
|
|
sizeof(struct sockaddr_in));
|
|
|
|
}
|
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&mask, 0, sizeof(mask));
|
2019-01-25 17:31:51 +01:00
|
|
|
masklen2ip(p->prefixlen, &mask.sin_addr);
|
|
|
|
mask.sin_family = p->family;
|
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
|
|
|
mask.sin_len = sizeof(struct sockaddr_in);
|
|
|
|
#endif
|
|
|
|
memcpy(&addreq.ifra_mask, &mask, sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
ret = if_ioctl(SIOCAIFADDR, (caddr_t)&addreq);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
return 0;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2019-01-25 17:31:51 +01:00
|
|
|
/*
|
|
|
|
* Helper for interface-addr un-install, non-netlink
|
|
|
|
*/
|
|
|
|
static int if_unset_prefix_ctx(const struct zebra_dplane_ctx *ctx)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2019-01-25 17:31:51 +01:00
|
|
|
int ret;
|
|
|
|
struct ifaliasreq addreq;
|
|
|
|
struct sockaddr_in addr, mask, peer;
|
|
|
|
struct prefix_ipv4 *p;
|
|
|
|
|
|
|
|
p = (struct prefix_ipv4 *)dplane_ctx_get_intf_addr(ctx);
|
|
|
|
|
|
|
|
memset(&addreq, 0, sizeof(addreq));
|
2019-05-08 20:33:53 +02:00
|
|
|
strlcpy((char *)&addreq.ifra_name, dplane_ctx_get_ifname(ctx),
|
2019-01-25 17:31:51 +01:00
|
|
|
sizeof(addreq.ifra_name));
|
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&addr, 0, sizeof(addr));
|
2019-01-25 17:31:51 +01:00
|
|
|
addr.sin_addr = p->prefix;
|
|
|
|
addr.sin_family = p->family;
|
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
|
|
|
addr.sin_len = sizeof(struct sockaddr_in);
|
|
|
|
#endif
|
|
|
|
memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
if (dplane_ctx_intf_is_connected(ctx)) {
|
|
|
|
p = (struct prefix_ipv4 *)dplane_ctx_get_intf_dest(ctx);
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&mask, 0, sizeof(mask));
|
2019-01-25 17:31:51 +01:00
|
|
|
peer.sin_addr = p->prefix;
|
|
|
|
peer.sin_family = p->family;
|
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
|
|
|
peer.sin_len = sizeof(struct sockaddr_in);
|
|
|
|
#endif
|
|
|
|
memcpy(&addreq.ifra_broadaddr, &peer,
|
|
|
|
sizeof(struct sockaddr_in));
|
|
|
|
}
|
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&mask, 0, sizeof(mask));
|
2019-01-25 17:31:51 +01:00
|
|
|
masklen2ip(p->prefixlen, &mask.sin_addr);
|
|
|
|
mask.sin_family = p->family;
|
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
|
|
|
mask.sin_len = sizeof(struct sockaddr_in);
|
|
|
|
#endif
|
|
|
|
memcpy(&addreq.ifra_mask, &mask, sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
ret = if_ioctl(SIOCDIFADDR, (caddr_t)&addreq);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
return 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
/* Set up interface's address, netmask (and broadcas? ). Linux or
|
|
|
|
Solaris uses ifname:number semantics to set IP address aliases. */
|
2019-02-12 17:10:04 +01:00
|
|
|
int if_set_prefix_ctx(const struct zebra_dplane_ctx *ctx)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct ifreq ifreq;
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
struct sockaddr_in broad;
|
|
|
|
struct sockaddr_in mask;
|
|
|
|
struct prefix_ipv4 ifaddr;
|
|
|
|
struct prefix_ipv4 *p;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-02-12 17:10:04 +01:00
|
|
|
p = (struct prefix_ipv4 *)dplane_ctx_get_intf_addr(ctx);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
ifaddr = *p;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-02-12 17:10:04 +01:00
|
|
|
strlcpy(ifreq.ifr_name, dplane_ctx_get_ifname(ctx),
|
|
|
|
sizeof(ifreq.ifr_name));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
addr.sin_addr = p->prefix;
|
|
|
|
addr.sin_family = p->family;
|
|
|
|
memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in));
|
|
|
|
ret = if_ioctl(SIOCSIFADDR, (caddr_t)&ifreq);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* We need mask for make broadcast addr. */
|
|
|
|
masklen2ip(p->prefixlen, &mask.sin_addr);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-02-12 17:10:04 +01:00
|
|
|
if (dplane_ctx_intf_is_broadcast(ctx)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
apply_mask_ipv4(&ifaddr);
|
|
|
|
addr.sin_addr = ifaddr.prefix;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
broad.sin_addr.s_addr =
|
|
|
|
(addr.sin_addr.s_addr | ~mask.sin_addr.s_addr);
|
|
|
|
broad.sin_family = p->family;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
memcpy(&ifreq.ifr_broadaddr, &broad,
|
|
|
|
sizeof(struct sockaddr_in));
|
|
|
|
ret = if_ioctl(SIOCSIFBRDADDR, (caddr_t)&ifreq);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
mask.sin_family = p->family;
|
2019-02-12 17:10:04 +01:00
|
|
|
memcpy(&ifreq.ifr_addr, &mask, sizeof(struct sockaddr_in));
|
2002-12-13 21:15:29 +01:00
|
|
|
ret = if_ioctl(SIOCSIFNETMASK, (caddr_t)&ifreq);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set up interface's address, netmask (and broadcas? ). Linux or
|
|
|
|
Solaris uses ifname:number semantics to set IP address aliases. */
|
2019-02-12 17:10:04 +01:00
|
|
|
int if_unset_prefix_ctx(const struct zebra_dplane_ctx *ctx)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct ifreq ifreq;
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
struct prefix_ipv4 *p;
|
|
|
|
|
2019-02-12 17:10:04 +01:00
|
|
|
p = (struct prefix_ipv4 *)dplane_ctx_get_intf_addr(ctx);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-02-12 17:10:04 +01:00
|
|
|
strlcpy(ifreq.ifr_name, dplane_ctx_get_ifname(ctx),
|
|
|
|
sizeof(ifreq.ifr_name));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&addr, 0, sizeof(addr));
|
2002-12-13 21:15:29 +01:00
|
|
|
addr.sin_family = p->family;
|
|
|
|
memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in));
|
|
|
|
ret = if_ioctl(SIOCSIFADDR, (caddr_t)&ifreq);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
[autoconf] bugs 162,303,178: Fix 'present but can not be compiled' warnings
2007-05-09 Paul Jakma <paul.jakma@sun.com>
* configure.ac: sys/conf.h depends on sys/param.h, at least on
FBSD 6.2.
(bug #363) Should check for in_pktinfo for IRDP
2006-05-27 Paul Jakma <paul.jakma@sun.com>
* configure.ac: General cleanup of header and type checks, introducing
an internal define, QUAGGA_INCLUDES, to build up a list of
stuff to include so as to avoid 'present but cant be compiled'
warnings.
Misc additional checks of things missing according to autoscan.
Add LIBM, for bgpd's use of libm, so as to avoid burdening
LIBS, and all the binaries, with libm linkage.
Remove the bad practice of using m4 changequote(), just
quote the []'s in the case statements properly.
This should fix bugs 162, 303 and 178.
* */*.{c,h}: Update all HAVE_* to the standard autoconf namespaced
HAVE_* defines. I.e. HAVE_SA_LEN -> HAVE_STRUCT_SOCKADDR_SA_LEN,
* bgpd/Makefile.am: Add LIBM to bgpd's LDADD, for pow().
2007-05-10 04:38:51 +02:00
|
|
|
#endif /* HAVE_STRUCT_IFALIASREQ */
|
2002-12-13 21:15:29 +01:00
|
|
|
#endif /* HAVE_NETLINK */
|
|
|
|
|
2024-09-20 03:39:50 +02:00
|
|
|
#ifndef HAVE_NETLINK
|
2002-12-13 21:15:29 +01:00
|
|
|
/* get interface flags */
|
|
|
|
void if_get_flags(struct interface *ifp)
|
|
|
|
{
|
|
|
|
int ret;
|
2022-03-24 17:57:01 +01:00
|
|
|
struct ifreq ifreqflags = {};
|
|
|
|
struct ifreq ifreqdata = {};
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2022-02-01 08:33:00 +01:00
|
|
|
ifreq_set_name(&ifreqflags, ifp);
|
|
|
|
ifreq_set_name(&ifreqdata, ifp);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2022-02-01 08:33:00 +01:00
|
|
|
ret = vrf_if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreqflags,
|
|
|
|
ifp->vrf->vrf_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret < 0) {
|
2018-09-13 21:34:28 +02:00
|
|
|
flog_err_sys(EC_LIB_SYSTEM_CALL,
|
2020-10-12 21:53:14 +02:00
|
|
|
"vrf_if_ioctl(SIOCGIFFLAGS %s) failed: %s",
|
|
|
|
ifp->name, safe_strerror(errno));
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
}
|
2008-07-01 20:24:58 +02:00
|
|
|
|
2020-10-12 21:53:14 +02:00
|
|
|
if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
/* Per-default, IFF_RUNNING is held high, unless link-detect
|
|
|
|
* says otherwise - we abuse IFF_RUNNING inside zebra as a
|
|
|
|
* link-state flag, following practice on Linux and Solaris
|
|
|
|
* kernels
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef SIOCGIFDATA
|
|
|
|
/*
|
|
|
|
* BSD gets link state from ifi_link_link in struct if_data.
|
|
|
|
* All BSD's have this in getifaddrs(3) ifa_data for AF_LINK
|
|
|
|
* addresses. We can also access it via SIOCGIFDATA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef __NetBSD__
|
|
|
|
struct ifdatareq ifdr = {.ifdr_data.ifi_link_state = 0};
|
|
|
|
struct if_data *ifdata = &ifdr.ifdr_data;
|
|
|
|
|
|
|
|
strlcpy(ifdr.ifdr_name, ifp->name, sizeof(ifdr.ifdr_name));
|
2021-10-22 00:17:40 +02:00
|
|
|
ret = vrf_if_ioctl(SIOCGIFDATA, (caddr_t)&ifdr, ifp->vrf->vrf_id);
|
2020-10-12 21:53:14 +02:00
|
|
|
#else
|
|
|
|
struct if_data ifd = {.ifi_link_state = 0};
|
|
|
|
struct if_data *ifdata = &ifd;
|
|
|
|
|
2022-02-01 08:33:00 +01:00
|
|
|
ifreqdata.ifr_data = (caddr_t)ifdata;
|
|
|
|
ret = vrf_if_ioctl(SIOCGIFDATA, (caddr_t)&ifreqdata, ifp->vrf->vrf_id);
|
2020-10-12 21:53:14 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
if (ret == -1)
|
|
|
|
/* Very unlikely. Did the interface disappear? */
|
|
|
|
flog_err_sys(EC_LIB_SYSTEM_CALL,
|
|
|
|
"if_ioctl(SIOCGIFDATA %s) failed: %s", ifp->name,
|
|
|
|
safe_strerror(errno));
|
|
|
|
else {
|
|
|
|
if (ifdata->ifi_link_state >= LINK_STATE_UP)
|
2022-02-01 08:33:00 +01:00
|
|
|
SET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING);
|
2020-10-12 21:53:14 +02:00
|
|
|
else if (ifdata->ifi_link_state == LINK_STATE_UNKNOWN)
|
|
|
|
/* BSD traditionally treats UNKNOWN as UP */
|
2022-02-01 08:33:00 +01:00
|
|
|
SET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING);
|
2020-10-12 21:53:14 +02:00
|
|
|
else
|
2022-02-01 08:33:00 +01:00
|
|
|
UNSET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING);
|
2020-10-12 21:53:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(HAVE_BSD_LINK_DETECT)
|
|
|
|
/*
|
|
|
|
* This is only needed for FreeBSD older than FreeBSD-13.
|
|
|
|
* Valid and active media generally means the link state is
|
|
|
|
* up, but this is not always the case.
|
|
|
|
* For example, some BSD's with a net80211 interface in MONITOR
|
|
|
|
* mode will treat the media as valid and active but the
|
|
|
|
* link state is down - because we cannot send anything.
|
|
|
|
* Also, virtual interfaces such as PPP, VLAN, etc generally
|
|
|
|
* don't support media at all, so the ioctl will just fail.
|
2008-07-01 20:24:58 +02:00
|
|
|
*/
|
2020-10-12 21:53:14 +02:00
|
|
|
struct ifmediareq ifmr = {.ifm_status = 0};
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-10-12 21:53:14 +02:00
|
|
|
strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-10-12 21:53:14 +02:00
|
|
|
if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) == -1) {
|
|
|
|
if (errno != EINVAL)
|
2018-09-13 21:34:28 +02:00
|
|
|
flog_err_sys(EC_LIB_SYSTEM_CALL,
|
2020-10-12 21:53:14 +02:00
|
|
|
"if_ioctl(SIOCGIFMEDIA %s) failed: %s",
|
|
|
|
ifp->name, safe_strerror(errno));
|
|
|
|
} else if (ifmr.ifm_status & IFM_AVALID) { /* media state is valid */
|
|
|
|
if (ifmr.ifm_status & IFM_ACTIVE) /* media is active */
|
2022-02-01 08:33:00 +01:00
|
|
|
SET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING);
|
2020-10-12 21:53:14 +02:00
|
|
|
else
|
2022-02-01 08:33:00 +01:00
|
|
|
UNSET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING);
|
2008-07-01 20:24:58 +02:00
|
|
|
}
|
2008-01-10 16:24:32 +01:00
|
|
|
#endif /* HAVE_BSD_LINK_DETECT */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-12 21:53:14 +02:00
|
|
|
out:
|
2022-02-01 08:33:00 +01:00
|
|
|
if_flags_update(ifp, (ifreqflags.ifr_flags & 0x0000ffff));
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2024-09-20 03:39:50 +02:00
|
|
|
#endif
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Set interface flags */
|
[zebra/solaris] Interface state fixups for Solaris.
2006-01-25 Paul Jakma <paul.jakma@sun.com>
* (general) More solaris PF_ROUTE hacks. The IFF_UP mangling
for solaris was incomplete on the PF_ROUTE side. fix it.
This changeset generally uglifies things. For some future
work I'd like to see the state changes seperated out from
the details of the code. Differences between systems might
then be slightly easier to implement without convoluted
hacks.
Changes should be specific to Solaris mostly, however
also tested on FreeBSD 6.
* if_ioctl_solaris.c: (interface_list_ioctl) ignore ~IFF_UP
interfaces, we'll hear about them when/if interface goes up
through NEWADDR.
Update flags explicitely at end of it to kick mangling.
* ioctl_solaris.c: (if_mangle_up) removed to interface.c, in
kind.
(lifreq_set_name) more convenient to take the string, than
the ifp.
(if_get_flags_direct) new convenience function, returns
the actual flags. Used during bootstrap in if_ioctl_solaris.c
to peek at flags of logical interfaces to see whether or
not to ignore them.
(if_get_flags) ENXIO means it's gone, poke out IFF_UP and
kick flags update.
(if_{un,}set_flags) flags argument should be 64bit.
* ioctl.{c,h}: flags argument should be 64bit.
* interface.h: Add a 'primary_state' flag to struct zebra_if on
SUNOS_5.
Export if_flags_update.
* interface.c: (if_flags_mangle) moved over in kind from
ioctl_solaris.c. Nasty kludge to try get IFF_UP right, as
much as is possible. Also keep track of the actual IFF_UP
value for the primary interface, so we can know when the ifp
must be deleted.
(if_flags_update) Take a new interface flags value, apply it
to the interface, and take whatever actions are required due
to flag transitions.
(if_refresh) flag state change logic is moved out to
previous. Just call if_get_flags, which will end up using
previous to effect the update of flags.
(if_flag_dump_vty) IFF_IPV{4,6} aren't interesting, VIRTUAL
and NOXMIT are though.
* kernel_socket.c: (ifm_read) Down->Down transitions shouldn't
create ifp, for non-IFANNOUNCE systems.
Use if_flags_update to update flags.
flag transition logic is now handled automatically through
if_flags_update.
(ifam_read) Better to call if_refresh *after* adding
connected addresses, as connected count affects IFF_UP on
IFF_UP-mangled systems.
On Solaris, Up->Down due to DELADDR means we need to delete
the ifp - the IFINFO might already have been and gone.
* rt.h: include other dependent headers.
2006-01-25 05:31:40 +01:00
|
|
|
int if_set_flags(struct interface *ifp, uint64_t flags)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct ifreq ifreq;
|
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&ifreq, 0, sizeof(ifreq));
|
2002-12-13 21:15:29 +01:00
|
|
|
ifreq_set_name(&ifreq, ifp);
|
|
|
|
|
|
|
|
ifreq.ifr_flags = ifp->flags;
|
|
|
|
ifreq.ifr_flags |= flags;
|
|
|
|
|
2021-10-22 00:17:40 +02:00
|
|
|
ret = vrf_if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq, ifp->vrf->vrf_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (ret < 0) {
|
2022-06-15 13:31:53 +02:00
|
|
|
zlog_info("can't set interface %s(%u) flags %" PRIu64,
|
|
|
|
ifp->name, ifp->vrf->vrf_id, flags);
|
2002-12-13 21:15:29 +01:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unset interface's flag. */
|
[zebra/solaris] Interface state fixups for Solaris.
2006-01-25 Paul Jakma <paul.jakma@sun.com>
* (general) More solaris PF_ROUTE hacks. The IFF_UP mangling
for solaris was incomplete on the PF_ROUTE side. fix it.
This changeset generally uglifies things. For some future
work I'd like to see the state changes seperated out from
the details of the code. Differences between systems might
then be slightly easier to implement without convoluted
hacks.
Changes should be specific to Solaris mostly, however
also tested on FreeBSD 6.
* if_ioctl_solaris.c: (interface_list_ioctl) ignore ~IFF_UP
interfaces, we'll hear about them when/if interface goes up
through NEWADDR.
Update flags explicitely at end of it to kick mangling.
* ioctl_solaris.c: (if_mangle_up) removed to interface.c, in
kind.
(lifreq_set_name) more convenient to take the string, than
the ifp.
(if_get_flags_direct) new convenience function, returns
the actual flags. Used during bootstrap in if_ioctl_solaris.c
to peek at flags of logical interfaces to see whether or
not to ignore them.
(if_get_flags) ENXIO means it's gone, poke out IFF_UP and
kick flags update.
(if_{un,}set_flags) flags argument should be 64bit.
* ioctl.{c,h}: flags argument should be 64bit.
* interface.h: Add a 'primary_state' flag to struct zebra_if on
SUNOS_5.
Export if_flags_update.
* interface.c: (if_flags_mangle) moved over in kind from
ioctl_solaris.c. Nasty kludge to try get IFF_UP right, as
much as is possible. Also keep track of the actual IFF_UP
value for the primary interface, so we can know when the ifp
must be deleted.
(if_flags_update) Take a new interface flags value, apply it
to the interface, and take whatever actions are required due
to flag transitions.
(if_refresh) flag state change logic is moved out to
previous. Just call if_get_flags, which will end up using
previous to effect the update of flags.
(if_flag_dump_vty) IFF_IPV{4,6} aren't interesting, VIRTUAL
and NOXMIT are though.
* kernel_socket.c: (ifm_read) Down->Down transitions shouldn't
create ifp, for non-IFANNOUNCE systems.
Use if_flags_update to update flags.
flag transition logic is now handled automatically through
if_flags_update.
(ifam_read) Better to call if_refresh *after* adding
connected addresses, as connected count affects IFF_UP on
IFF_UP-mangled systems.
On Solaris, Up->Down due to DELADDR means we need to delete
the ifp - the IFINFO might already have been and gone.
* rt.h: include other dependent headers.
2006-01-25 05:31:40 +01:00
|
|
|
int if_unset_flags(struct interface *ifp, uint64_t flags)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct ifreq ifreq;
|
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&ifreq, 0, sizeof(ifreq));
|
2002-12-13 21:15:29 +01:00
|
|
|
ifreq_set_name(&ifreq, ifp);
|
|
|
|
|
|
|
|
ifreq.ifr_flags = ifp->flags;
|
|
|
|
ifreq.ifr_flags &= ~flags;
|
|
|
|
|
2021-10-22 00:17:40 +02:00
|
|
|
ret = vrf_if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq, ifp->vrf->vrf_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (ret < 0) {
|
2022-06-15 13:31:53 +02:00
|
|
|
zlog_warn("can't unset interface %s(%u) flags %" PRIu64,
|
|
|
|
ifp->name, ifp->vrf->vrf_id, flags);
|
2002-12-13 21:15:29 +01:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-02-12 17:10:04 +01:00
|
|
|
#ifndef LINUX_IPV6 /* Netlink has its own code */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
[autoconf] bugs 162,303,178: Fix 'present but can not be compiled' warnings
2007-05-09 Paul Jakma <paul.jakma@sun.com>
* configure.ac: sys/conf.h depends on sys/param.h, at least on
FBSD 6.2.
(bug #363) Should check for in_pktinfo for IRDP
2006-05-27 Paul Jakma <paul.jakma@sun.com>
* configure.ac: General cleanup of header and type checks, introducing
an internal define, QUAGGA_INCLUDES, to build up a list of
stuff to include so as to avoid 'present but cant be compiled'
warnings.
Misc additional checks of things missing according to autoscan.
Add LIBM, for bgpd's use of libm, so as to avoid burdening
LIBS, and all the binaries, with libm linkage.
Remove the bad practice of using m4 changequote(), just
quote the []'s in the case statements properly.
This should fix bugs 162, 303 and 178.
* */*.{c,h}: Update all HAVE_* to the standard autoconf namespaced
HAVE_* defines. I.e. HAVE_SA_LEN -> HAVE_STRUCT_SOCKADDR_SA_LEN,
* bgpd/Makefile.am: Add LIBM to bgpd's LDADD, for pow().
2007-05-10 04:38:51 +02:00
|
|
|
#ifdef HAVE_STRUCT_IN6_ALIASREQ
|
2002-12-13 21:15:29 +01:00
|
|
|
#ifndef ND6_INFINITE_LIFETIME
|
|
|
|
#define ND6_INFINITE_LIFETIME 0xffffffffL
|
|
|
|
#endif /* ND6_INFINITE_LIFETIME */
|
2019-01-25 17:31:51 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Helper for interface-addr install, non-netlink
|
|
|
|
*/
|
|
|
|
static int if_set_prefix6_ctx(const struct zebra_dplane_ctx *ctx)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct in6_aliasreq addreq;
|
|
|
|
struct sockaddr_in6 addr;
|
|
|
|
struct sockaddr_in6 mask;
|
|
|
|
struct prefix_ipv6 *p;
|
|
|
|
|
|
|
|
p = (struct prefix_ipv6 *)dplane_ctx_get_intf_addr(ctx);
|
|
|
|
|
|
|
|
memset(&addreq, 0, sizeof(addreq));
|
2019-02-12 17:10:04 +01:00
|
|
|
strlcpy((char *)&addreq.ifra_name,
|
2019-01-25 17:31:51 +01:00
|
|
|
dplane_ctx_get_ifname(ctx), sizeof(addreq.ifra_name));
|
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&addr, 0, sizeof(addr));
|
2019-01-25 17:31:51 +01:00
|
|
|
addr.sin6_addr = p->prefix;
|
|
|
|
addr.sin6_family = p->family;
|
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
|
|
|
addr.sin6_len = sizeof(struct sockaddr_in6);
|
|
|
|
#endif
|
|
|
|
memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in6));
|
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&mask, 0, sizeof(mask));
|
2019-01-25 17:31:51 +01:00
|
|
|
masklen2ip6(p->prefixlen, &mask.sin6_addr);
|
|
|
|
mask.sin6_family = p->family;
|
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
|
|
|
mask.sin6_len = sizeof(struct sockaddr_in6);
|
|
|
|
#endif
|
|
|
|
memcpy(&addreq.ifra_prefixmask, &mask, sizeof(struct sockaddr_in6));
|
|
|
|
|
|
|
|
addreq.ifra_lifetime.ia6t_vltime = 0xffffffff;
|
|
|
|
addreq.ifra_lifetime.ia6t_pltime = 0xffffffff;
|
|
|
|
|
|
|
|
#ifdef HAVE_STRUCT_IF6_ALIASREQ_IFRA_LIFETIME
|
|
|
|
addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
|
|
|
|
addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
ret = if_ioctl_ipv6(SIOCAIFADDR_IN6, (caddr_t)&addreq);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Helper for interface-addr un-install, non-netlink
|
|
|
|
*/
|
|
|
|
static int if_unset_prefix6_ctx(const struct zebra_dplane_ctx *ctx)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct in6_aliasreq addreq;
|
|
|
|
struct sockaddr_in6 addr;
|
|
|
|
struct sockaddr_in6 mask;
|
|
|
|
struct prefix_ipv6 *p;
|
|
|
|
|
|
|
|
p = (struct prefix_ipv6 *)dplane_ctx_get_intf_addr(ctx);
|
|
|
|
|
|
|
|
memset(&addreq, 0, sizeof(addreq));
|
2019-02-12 17:10:04 +01:00
|
|
|
strlcpy((char *)&addreq.ifra_name,
|
2019-01-25 17:31:51 +01:00
|
|
|
dplane_ctx_get_ifname(ctx), sizeof(addreq.ifra_name));
|
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&addr, 0, sizeof(addr));
|
2019-01-25 17:31:51 +01:00
|
|
|
addr.sin6_addr = p->prefix;
|
|
|
|
addr.sin6_family = p->family;
|
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
|
|
|
addr.sin6_len = sizeof(struct sockaddr_in6);
|
|
|
|
#endif
|
|
|
|
memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in6));
|
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&mask, 0, sizeof(mask));
|
2019-01-25 17:31:51 +01:00
|
|
|
masklen2ip6(p->prefixlen, &mask.sin6_addr);
|
|
|
|
mask.sin6_family = p->family;
|
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
|
|
|
mask.sin6_len = sizeof(struct sockaddr_in6);
|
|
|
|
#endif
|
|
|
|
memcpy(&addreq.ifra_prefixmask, &mask, sizeof(struct sockaddr_in6));
|
|
|
|
|
[autoconf] bugs 162,303,178: Fix 'present but can not be compiled' warnings
2007-05-09 Paul Jakma <paul.jakma@sun.com>
* configure.ac: sys/conf.h depends on sys/param.h, at least on
FBSD 6.2.
(bug #363) Should check for in_pktinfo for IRDP
2006-05-27 Paul Jakma <paul.jakma@sun.com>
* configure.ac: General cleanup of header and type checks, introducing
an internal define, QUAGGA_INCLUDES, to build up a list of
stuff to include so as to avoid 'present but cant be compiled'
warnings.
Misc additional checks of things missing according to autoscan.
Add LIBM, for bgpd's use of libm, so as to avoid burdening
LIBS, and all the binaries, with libm linkage.
Remove the bad practice of using m4 changequote(), just
quote the []'s in the case statements properly.
This should fix bugs 162, 303 and 178.
* */*.{c,h}: Update all HAVE_* to the standard autoconf namespaced
HAVE_* defines. I.e. HAVE_SA_LEN -> HAVE_STRUCT_SOCKADDR_SA_LEN,
* bgpd/Makefile.am: Add LIBM to bgpd's LDADD, for pow().
2007-05-10 04:38:51 +02:00
|
|
|
#ifdef HAVE_STRUCT_IF6_ALIASREQ_IFRA_LIFETIME
|
2002-12-13 21:15:29 +01:00
|
|
|
addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
|
|
|
|
addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
|
2003-05-25 23:04:54 +02:00
|
|
|
#endif
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
ret = if_ioctl_ipv6(SIOCDIFADDR_IN6, (caddr_t)&addreq);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#else
|
2019-02-12 17:10:04 +01:00
|
|
|
/* The old, pre-dataplane code here just returned, so we're retaining that
|
|
|
|
* choice.
|
|
|
|
*/
|
|
|
|
static int if_set_prefix6_ctx(const struct zebra_dplane_ctx *ctx)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-02-12 17:10:04 +01:00
|
|
|
static int if_unset_prefix6_ctx(const struct zebra_dplane_ctx *ctx)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
[autoconf] bugs 162,303,178: Fix 'present but can not be compiled' warnings
2007-05-09 Paul Jakma <paul.jakma@sun.com>
* configure.ac: sys/conf.h depends on sys/param.h, at least on
FBSD 6.2.
(bug #363) Should check for in_pktinfo for IRDP
2006-05-27 Paul Jakma <paul.jakma@sun.com>
* configure.ac: General cleanup of header and type checks, introducing
an internal define, QUAGGA_INCLUDES, to build up a list of
stuff to include so as to avoid 'present but cant be compiled'
warnings.
Misc additional checks of things missing according to autoscan.
Add LIBM, for bgpd's use of libm, so as to avoid burdening
LIBS, and all the binaries, with libm linkage.
Remove the bad practice of using m4 changequote(), just
quote the []'s in the case statements properly.
This should fix bugs 162, 303 and 178.
* */*.{c,h}: Update all HAVE_* to the standard autoconf namespaced
HAVE_* defines. I.e. HAVE_SA_LEN -> HAVE_STRUCT_SOCKADDR_SA_LEN,
* bgpd/Makefile.am: Add LIBM to bgpd's LDADD, for pow().
2007-05-10 04:38:51 +02:00
|
|
|
#endif /* HAVE_STRUCT_IN6_ALIASREQ */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#endif /* LINUX_IPV6 */
|