2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2002-12-13 21:15:29 +01:00
|
|
|
/*
|
|
|
|
* Interface looking up by ioctl ().
|
|
|
|
* 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
|
|
|
|
2017-07-26 19:49:15 +02:00
|
|
|
#ifdef OPEN_BSD
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "if.h"
|
|
|
|
#include "sockunion.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "ioctl.h"
|
|
|
|
#include "connected.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "log.h"
|
2014-07-03 12:23:09 +02:00
|
|
|
#include "vrf.h"
|
2015-12-22 21:24:25 +01:00
|
|
|
#include "vty.h"
|
2018-06-19 20:29:05 +02:00
|
|
|
#include "lib_errors.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#include "zebra/interface.h"
|
2014-07-03 12:23:09 +02:00
|
|
|
#include "zebra/rib.h"
|
2018-08-26 00:28:19 +02:00
|
|
|
#include "zebra/rt.h"
|
2018-08-24 19:14:09 +02:00
|
|
|
#include "zebra/zebra_errors.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-11-15 05:37:14 +01:00
|
|
|
#include <ifaddrs.h>
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Interface looking up using infamous SIOCGIFCONF. */
|
2005-06-28 19:17:12 +02:00
|
|
|
static int interface_list_ioctl(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
int sock;
|
|
|
|
#define IFNUM_BASE 32
|
|
|
|
int ifnum;
|
|
|
|
struct ifreq *ifreq;
|
|
|
|
struct ifconf ifconf;
|
|
|
|
struct interface *ifp;
|
|
|
|
int n;
|
|
|
|
int lastlen;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Normally SIOCGIFCONF works with AF_INET socket. */
|
|
|
|
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
|
if (sock < 0) {
|
2018-09-13 21:34:28 +02:00
|
|
|
flog_err_sys(EC_LIB_SOCKET,
|
2018-08-16 22:10:32 +02:00
|
|
|
"Can't make AF_INET socket stream: %s",
|
|
|
|
safe_strerror(errno));
|
2002-12-13 21:15:29 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set initial ifreq count. This will be double when SIOCGIFCONF
|
|
|
|
fail. Solaris has SIOCGIFNUM. */
|
|
|
|
#ifdef SIOCGIFNUM
|
|
|
|
ret = ioctl(sock, SIOCGIFNUM, &ifnum);
|
|
|
|
if (ret < 0)
|
|
|
|
ifnum = IFNUM_BASE;
|
|
|
|
else
|
|
|
|
ifnum++;
|
|
|
|
#else
|
|
|
|
ifnum = IFNUM_BASE;
|
|
|
|
#endif /* SIOCGIFNUM */
|
|
|
|
|
|
|
|
ifconf.ifc_buf = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
lastlen = 0;
|
|
|
|
/* Loop until SIOCGIFCONF success. */
|
|
|
|
for (;;) {
|
|
|
|
ifconf.ifc_len = sizeof(struct ifreq) * ifnum;
|
|
|
|
ifconf.ifc_buf =
|
|
|
|
XREALLOC(MTYPE_TMP, ifconf.ifc_buf, ifconf.ifc_len);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
ret = ioctl(sock, SIOCGIFCONF, &ifconf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
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, "SIOCGIFCONF: %s",
|
2018-08-16 22:10:32 +02:00
|
|
|
safe_strerror(errno));
|
2002-12-13 21:15:29 +01:00
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
/* Repeatedly get info til buffer fails to grow. */
|
|
|
|
if (ifconf.ifc_len > lastlen) {
|
|
|
|
lastlen = ifconf.ifc_len;
|
|
|
|
ifnum += 10;
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Success. */
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate interface. */
|
|
|
|
ifreq = ifconf.ifc_req;
|
|
|
|
|
|
|
|
#ifdef OPEN_BSD
|
|
|
|
for (n = 0; n < ifconf.ifc_len;) {
|
2017-01-19 01:31:52 +01:00
|
|
|
unsigned int size;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
ifreq = (struct ifreq *)((caddr_t)ifconf.ifc_req + n);
|
2021-10-13 14:06:38 +02:00
|
|
|
ifp = if_get_by_name(ifreq->ifr_name, VRF_DEFAULT,
|
|
|
|
VRF_DEFAULT_NAME);
|
2002-12-13 21:15:29 +01:00
|
|
|
if_add_update(ifp);
|
|
|
|
size = ifreq->ifr_addr.sa_len;
|
|
|
|
if (size < sizeof(ifreq->ifr_addr))
|
|
|
|
size = sizeof(ifreq->ifr_addr);
|
|
|
|
size += sizeof(ifreq->ifr_name);
|
|
|
|
n += size;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
for (n = 0; n < ifconf.ifc_len; n += sizeof(struct ifreq)) {
|
2021-10-13 14:06:38 +02:00
|
|
|
ifp = if_get_by_name(ifreq->ifr_name, VRF_DEFAULT,
|
|
|
|
VRF_DEFAULT_NAME);
|
2002-12-13 21:15:29 +01:00
|
|
|
if_add_update(ifp);
|
|
|
|
ifreq++;
|
|
|
|
}
|
|
|
|
#endif /* OPEN_BSD */
|
|
|
|
|
|
|
|
end:
|
|
|
|
close(sock);
|
|
|
|
XFREE(MTYPE_TMP, ifconf.ifc_buf);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get interface's index by ioctl. */
|
|
|
|
static int if_get_index(struct interface *ifp)
|
|
|
|
{
|
2017-10-03 03:06:04 +02:00
|
|
|
if_set_index(ifp, if_nametoindex(ifp->name));
|
2002-12-13 21:15:29 +01:00
|
|
|
return ifp->ifindex;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SIOCGIFHWADDR
|
|
|
|
static int if_get_hwaddr(struct interface *ifp)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct ifreq ifreq;
|
|
|
|
int i;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-02-25 18:37:34 +01:00
|
|
|
strlcpy(ifreq.ifr_name, ifp->name, sizeof(ifreq.ifr_name));
|
2002-12-13 21:15:29 +01:00
|
|
|
ifreq.ifr_addr.sa_family = AF_INET;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Fetch Hardware address if available. */
|
2021-10-22 00:17:40 +02:00
|
|
|
ret = vrf_if_ioctl(SIOCGIFHWADDR, (caddr_t)&ifreq, ifp->vrf->vrf_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret < 0)
|
|
|
|
ifp->hw_addr_len = 0;
|
|
|
|
else {
|
|
|
|
memcpy(ifp->hw_addr, ifreq.ifr_hwaddr.sa_data, 6);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (i = 0; i < 6; i++)
|
|
|
|
if (ifp->hw_addr[i] != 0)
|
|
|
|
break;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (i == 6)
|
|
|
|
ifp->hw_addr_len = 0;
|
|
|
|
else
|
|
|
|
ifp->hw_addr_len = 6;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif /* SIOCGIFHWADDR */
|
|
|
|
|
2005-06-28 19:17:12 +02:00
|
|
|
static int if_getaddrs(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct ifaddrs *ifap;
|
|
|
|
struct ifaddrs *ifapfree;
|
|
|
|
struct interface *ifp;
|
|
|
|
int prefixlen;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-11-20 03:06:59 +01:00
|
|
|
ret = getifaddrs(&ifap);
|
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, "getifaddrs(): %s",
|
2018-08-06 18:36:50 +02:00
|
|
|
safe_strerror(errno));
|
2002-12-13 21:15:29 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (ifapfree = ifap; ifap; ifap = ifap->ifa_next) {
|
|
|
|
if (ifap->ifa_addr == NULL) {
|
2018-08-03 20:03:29 +02:00
|
|
|
flog_err(
|
2018-09-13 21:34:28 +02:00
|
|
|
EC_LIB_INTERFACE,
|
2002-12-13 21:15:29 +01:00
|
|
|
"%s: nonsensical ifaddr with NULL ifa_addr, ifname %s",
|
2006-01-17 18:59:11 +01:00
|
|
|
__func__,
|
|
|
|
(ifap->ifa_name ? ifap->ifa_name : "(null)"));
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2019-06-24 01:46:39 +02:00
|
|
|
ifp = if_lookup_by_name(ifap->ifa_name, VRF_DEFAULT);
|
2006-01-17 18:59:11 +01:00
|
|
|
if (ifp == NULL) {
|
2018-09-13 21:34:28 +02:00
|
|
|
flog_err(EC_LIB_INTERFACE,
|
2022-09-13 08:28:35 +02:00
|
|
|
"%s: Can't lookup interface %s", __func__,
|
2018-09-13 21:38:57 +02:00
|
|
|
ifap->ifa_name);
|
2006-01-17 18:59:11 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ifap->ifa_addr->sa_family == AF_INET) {
|
|
|
|
struct sockaddr_in *addr;
|
|
|
|
struct sockaddr_in *mask;
|
|
|
|
struct sockaddr_in *dest;
|
[PtP over ethernet] New peer flag allows much more addressing flexibility
2006-12-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* if.h: (struct connected) Add new ZEBRA_IFA_PEER flag indicating
whether a peer address has been configured. Comment now shows
the new interpretation of the destination addr: if ZEBRA_IFA_PEER
is set, then it must contain the destination address, otherwise
it may contain the broadcast address or be NULL.
(CONNECTED_DEST_HOST,CONNECTED_POINTOPOINT_HOST) Remove obsolete
macros that were specific to IPv4 and not fully general.
(CONNECTED_PEER) New macro to check ZEBRA_IFA_PEER flag.
(CONNECTED_PREFIX) New macro giving the prefix to insert into
the RIB: if CONNECTED_PEER, then use the destination (peer) address,
else use the address field.
(CONNECTED_ID) New macro to come up with an identifying address
for the struct connected.
* if.c: (if_lookup_address, connected_lookup_address) Streamline
logic with new CONNECTED_PREFIX macro.
* prefix.h: (PREFIX_COPY_IPV4, PREFIX_COPY_IPV6) New macros
for better performance than the general prefix_copy function.
* zclient.c: (zebra_interface_address_read) For non-null destination
addresses, set prefixlen to equal the address prefixlen. This
is needed to get the new CONNECTED_PREFIX macro to work properly.
* connected.c: (connected_up_ipv4, connected_down_ipv4,
connected_up_ipv6, connected_down_ipv6) Simplify logic using the
new CONNECTED_PREFIX macro.
(connected_add_ipv4) Set prefixlen in destination addresses (required
by the CONNECTED_PREFIX macro). Use CONNECTED_PEER macro instead
of testing for IFF_POINTOPOINT. Delete invalid warning message.
Warn about cases where the ZEBRA_IFA_PEER is set but no
destination address has been supplied (and turn off the flag).
(connected_add_ipv6) Add new flags argument so callers may set
the ZEBRA_IFA_PEER flag. If peer/broadcast address satisfies
IN6_IS_ADDR_UNSPECIFIED, then reject it with a warning.
Set prefixlen in destination address so CONNECTED_PREFIX will work.
* connected.h: (connected_add_ipv6) Add new flags argument so
callers may set the ZEBRA_IFA_PEER flag.
* interface.c: (connected_dump_vty) Use CONNECTED_PEER macro
to decide whether the destination address is a peer or broadcast
address (instead of checking IFF_BROADCAST and IFF_POINTOPOINT).
* if_ioctl.c: (if_getaddrs) Instead of setting a peer address
only when the IFF_POINTOPOINT is set, we now accept a peer
address whenever it is available and not the same as the local
address. Otherwise (no peer address assigned), we check
for a broadcast address (regardless of the IFF_BROADCAST flag).
And must now pass a flags value of ZEBRA_IFA_PEER to
connected_add_ipv4 when a peer address is assigned.
The same new logic is used with the IPv6 code as well (and we
pass the new flags argument to connected_add_ipv6).
(if_get_addr) Do not bother to check IFF_POINTOPOINT: just
issue the SIOCGIFDSTADDR ioctl and see if we get back
a peer address not matching the local address (and set
the ZEBRA_IFA_PEER in that case). If there's no peer address,
try to grab SIOCGIFBRDADDR regardless of whether IFF_BROADCAST is set.
* if_ioctl_solaris.c: (if_get_addr) Just try the SIOCGLIFDSTADDR ioctl
without bothering to check the IFF_POINTOPOINT flag. And if
no peer address was found, just try the SIOCGLIFBRDADDR ioctl
without checking the IFF_BROADCAST flag. Call connected_add_ipv4
and connected_add_ipv6 with appropriate flags.
* if_proc.c: (ifaddr_proc_ipv6) Must pass new flags argument to
connected_add_ipv6.
* kernel_socket.c: (ifam_read) Must pass new flags argument to
connected_add_ipv6.
* rt_netlink.c: (netlink_interface_addr) Copy logic from iproute2
to determine local and possible peer address (so there's no longer
a test for IFF_POINTOPOINT). Set ZEBRA_IFA_PEER flag appropriately.
Pass new flags argument to connected_add_ipv6.
(netlink_address) Test !CONNECTED_PEER instead of if_is_broadcast
to determine whether the connected destination address is a
broadcast address.
* bgp_nexthop.c: (bgp_connected_add, bgp_connected_delete)
Simplify logic by using new CONNECTED_PREFIX macro.
* ospf_interface.c: (ospf_if_is_configured, ospf_if_lookup_by_prefix,
ospf_if_lookup_recv_if) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_lsa.c: (lsa_link_ptop_set) Using the new CONNECTED_PREFIX
macro, both options collapse into the same code.
* ospf_snmp.c: (ospf_snmp_if_update) Simplify logic using new
CONNECTED_ID macro.
(ospf_snmp_is_if_have_addr) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_vty.c: (show_ip_ospf_interface_sub) Use new CONNECTED_PEER macro
instead of testing the IFF_POINTOPOINT flag.
* ospfd.c: (ospf_network_match_iface) Use new CONNECTED_PEER macro
instead of testing with if_is_pointopoint. And add commented-out
code to implement alternative (in my opinion) more elegant behavior
that has no special-case treatment for PtP addresses.
(ospf_network_run) Use new CONNECTED_ID macro to simplify logic.
* rip_interface.c: (rip_interface_multicast_set) Use new CONNECTED_ID
macro to simplify logic.
(rip_request_interface_send) Fix minor bug: ipv4_broadcast_addr does
not give a useful result if prefixlen is 32 (we require a peer
address in such cases).
* ripd.c: (rip_update_interface) Fix same bug as above.
2006-12-12 20:18:21 +01:00
|
|
|
struct in_addr *dest_pnt;
|
2002-12-13 21:15:29 +01:00
|
|
|
int flags = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
addr = (struct sockaddr_in *)ifap->ifa_addr;
|
|
|
|
mask = (struct sockaddr_in *)ifap->ifa_netmask;
|
|
|
|
prefixlen = ip_masklen(mask->sin_addr);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
dest_pnt = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-08-28 04:39:18 +02:00
|
|
|
if (if_is_pointopoint(ifp) && ifap->ifa_dstaddr
|
[PtP over ethernet] New peer flag allows much more addressing flexibility
2006-12-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* if.h: (struct connected) Add new ZEBRA_IFA_PEER flag indicating
whether a peer address has been configured. Comment now shows
the new interpretation of the destination addr: if ZEBRA_IFA_PEER
is set, then it must contain the destination address, otherwise
it may contain the broadcast address or be NULL.
(CONNECTED_DEST_HOST,CONNECTED_POINTOPOINT_HOST) Remove obsolete
macros that were specific to IPv4 and not fully general.
(CONNECTED_PEER) New macro to check ZEBRA_IFA_PEER flag.
(CONNECTED_PREFIX) New macro giving the prefix to insert into
the RIB: if CONNECTED_PEER, then use the destination (peer) address,
else use the address field.
(CONNECTED_ID) New macro to come up with an identifying address
for the struct connected.
* if.c: (if_lookup_address, connected_lookup_address) Streamline
logic with new CONNECTED_PREFIX macro.
* prefix.h: (PREFIX_COPY_IPV4, PREFIX_COPY_IPV6) New macros
for better performance than the general prefix_copy function.
* zclient.c: (zebra_interface_address_read) For non-null destination
addresses, set prefixlen to equal the address prefixlen. This
is needed to get the new CONNECTED_PREFIX macro to work properly.
* connected.c: (connected_up_ipv4, connected_down_ipv4,
connected_up_ipv6, connected_down_ipv6) Simplify logic using the
new CONNECTED_PREFIX macro.
(connected_add_ipv4) Set prefixlen in destination addresses (required
by the CONNECTED_PREFIX macro). Use CONNECTED_PEER macro instead
of testing for IFF_POINTOPOINT. Delete invalid warning message.
Warn about cases where the ZEBRA_IFA_PEER is set but no
destination address has been supplied (and turn off the flag).
(connected_add_ipv6) Add new flags argument so callers may set
the ZEBRA_IFA_PEER flag. If peer/broadcast address satisfies
IN6_IS_ADDR_UNSPECIFIED, then reject it with a warning.
Set prefixlen in destination address so CONNECTED_PREFIX will work.
* connected.h: (connected_add_ipv6) Add new flags argument so
callers may set the ZEBRA_IFA_PEER flag.
* interface.c: (connected_dump_vty) Use CONNECTED_PEER macro
to decide whether the destination address is a peer or broadcast
address (instead of checking IFF_BROADCAST and IFF_POINTOPOINT).
* if_ioctl.c: (if_getaddrs) Instead of setting a peer address
only when the IFF_POINTOPOINT is set, we now accept a peer
address whenever it is available and not the same as the local
address. Otherwise (no peer address assigned), we check
for a broadcast address (regardless of the IFF_BROADCAST flag).
And must now pass a flags value of ZEBRA_IFA_PEER to
connected_add_ipv4 when a peer address is assigned.
The same new logic is used with the IPv6 code as well (and we
pass the new flags argument to connected_add_ipv6).
(if_get_addr) Do not bother to check IFF_POINTOPOINT: just
issue the SIOCGIFDSTADDR ioctl and see if we get back
a peer address not matching the local address (and set
the ZEBRA_IFA_PEER in that case). If there's no peer address,
try to grab SIOCGIFBRDADDR regardless of whether IFF_BROADCAST is set.
* if_ioctl_solaris.c: (if_get_addr) Just try the SIOCGLIFDSTADDR ioctl
without bothering to check the IFF_POINTOPOINT flag. And if
no peer address was found, just try the SIOCGLIFBRDADDR ioctl
without checking the IFF_BROADCAST flag. Call connected_add_ipv4
and connected_add_ipv6 with appropriate flags.
* if_proc.c: (ifaddr_proc_ipv6) Must pass new flags argument to
connected_add_ipv6.
* kernel_socket.c: (ifam_read) Must pass new flags argument to
connected_add_ipv6.
* rt_netlink.c: (netlink_interface_addr) Copy logic from iproute2
to determine local and possible peer address (so there's no longer
a test for IFF_POINTOPOINT). Set ZEBRA_IFA_PEER flag appropriately.
Pass new flags argument to connected_add_ipv6.
(netlink_address) Test !CONNECTED_PEER instead of if_is_broadcast
to determine whether the connected destination address is a
broadcast address.
* bgp_nexthop.c: (bgp_connected_add, bgp_connected_delete)
Simplify logic by using new CONNECTED_PREFIX macro.
* ospf_interface.c: (ospf_if_is_configured, ospf_if_lookup_by_prefix,
ospf_if_lookup_recv_if) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_lsa.c: (lsa_link_ptop_set) Using the new CONNECTED_PREFIX
macro, both options collapse into the same code.
* ospf_snmp.c: (ospf_snmp_if_update) Simplify logic using new
CONNECTED_ID macro.
(ospf_snmp_is_if_have_addr) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_vty.c: (show_ip_ospf_interface_sub) Use new CONNECTED_PEER macro
instead of testing the IFF_POINTOPOINT flag.
* ospfd.c: (ospf_network_match_iface) Use new CONNECTED_PEER macro
instead of testing with if_is_pointopoint. And add commented-out
code to implement alternative (in my opinion) more elegant behavior
that has no special-case treatment for PtP addresses.
(ospf_network_run) Use new CONNECTED_ID macro to simplify logic.
* rip_interface.c: (rip_interface_multicast_set) Use new CONNECTED_ID
macro to simplify logic.
(rip_request_interface_send) Fix minor bug: ipv4_broadcast_addr does
not give a useful result if prefixlen is 32 (we require a peer
address in such cases).
* ripd.c: (rip_update_interface) Fix same bug as above.
2006-12-12 20:18:21 +01:00
|
|
|
&& !IPV4_ADDR_SAME(&addr->sin_addr,
|
|
|
|
&((struct sockaddr_in *)
|
|
|
|
ifap->ifa_dstaddr)
|
|
|
|
->sin_addr)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
dest = (struct sockaddr_in *)ifap->ifa_dstaddr;
|
|
|
|
dest_pnt = &dest->sin_addr;
|
[PtP over ethernet] New peer flag allows much more addressing flexibility
2006-12-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* if.h: (struct connected) Add new ZEBRA_IFA_PEER flag indicating
whether a peer address has been configured. Comment now shows
the new interpretation of the destination addr: if ZEBRA_IFA_PEER
is set, then it must contain the destination address, otherwise
it may contain the broadcast address or be NULL.
(CONNECTED_DEST_HOST,CONNECTED_POINTOPOINT_HOST) Remove obsolete
macros that were specific to IPv4 and not fully general.
(CONNECTED_PEER) New macro to check ZEBRA_IFA_PEER flag.
(CONNECTED_PREFIX) New macro giving the prefix to insert into
the RIB: if CONNECTED_PEER, then use the destination (peer) address,
else use the address field.
(CONNECTED_ID) New macro to come up with an identifying address
for the struct connected.
* if.c: (if_lookup_address, connected_lookup_address) Streamline
logic with new CONNECTED_PREFIX macro.
* prefix.h: (PREFIX_COPY_IPV4, PREFIX_COPY_IPV6) New macros
for better performance than the general prefix_copy function.
* zclient.c: (zebra_interface_address_read) For non-null destination
addresses, set prefixlen to equal the address prefixlen. This
is needed to get the new CONNECTED_PREFIX macro to work properly.
* connected.c: (connected_up_ipv4, connected_down_ipv4,
connected_up_ipv6, connected_down_ipv6) Simplify logic using the
new CONNECTED_PREFIX macro.
(connected_add_ipv4) Set prefixlen in destination addresses (required
by the CONNECTED_PREFIX macro). Use CONNECTED_PEER macro instead
of testing for IFF_POINTOPOINT. Delete invalid warning message.
Warn about cases where the ZEBRA_IFA_PEER is set but no
destination address has been supplied (and turn off the flag).
(connected_add_ipv6) Add new flags argument so callers may set
the ZEBRA_IFA_PEER flag. If peer/broadcast address satisfies
IN6_IS_ADDR_UNSPECIFIED, then reject it with a warning.
Set prefixlen in destination address so CONNECTED_PREFIX will work.
* connected.h: (connected_add_ipv6) Add new flags argument so
callers may set the ZEBRA_IFA_PEER flag.
* interface.c: (connected_dump_vty) Use CONNECTED_PEER macro
to decide whether the destination address is a peer or broadcast
address (instead of checking IFF_BROADCAST and IFF_POINTOPOINT).
* if_ioctl.c: (if_getaddrs) Instead of setting a peer address
only when the IFF_POINTOPOINT is set, we now accept a peer
address whenever it is available and not the same as the local
address. Otherwise (no peer address assigned), we check
for a broadcast address (regardless of the IFF_BROADCAST flag).
And must now pass a flags value of ZEBRA_IFA_PEER to
connected_add_ipv4 when a peer address is assigned.
The same new logic is used with the IPv6 code as well (and we
pass the new flags argument to connected_add_ipv6).
(if_get_addr) Do not bother to check IFF_POINTOPOINT: just
issue the SIOCGIFDSTADDR ioctl and see if we get back
a peer address not matching the local address (and set
the ZEBRA_IFA_PEER in that case). If there's no peer address,
try to grab SIOCGIFBRDADDR regardless of whether IFF_BROADCAST is set.
* if_ioctl_solaris.c: (if_get_addr) Just try the SIOCGLIFDSTADDR ioctl
without bothering to check the IFF_POINTOPOINT flag. And if
no peer address was found, just try the SIOCGLIFBRDADDR ioctl
without checking the IFF_BROADCAST flag. Call connected_add_ipv4
and connected_add_ipv6 with appropriate flags.
* if_proc.c: (ifaddr_proc_ipv6) Must pass new flags argument to
connected_add_ipv6.
* kernel_socket.c: (ifam_read) Must pass new flags argument to
connected_add_ipv6.
* rt_netlink.c: (netlink_interface_addr) Copy logic from iproute2
to determine local and possible peer address (so there's no longer
a test for IFF_POINTOPOINT). Set ZEBRA_IFA_PEER flag appropriately.
Pass new flags argument to connected_add_ipv6.
(netlink_address) Test !CONNECTED_PEER instead of if_is_broadcast
to determine whether the connected destination address is a
broadcast address.
* bgp_nexthop.c: (bgp_connected_add, bgp_connected_delete)
Simplify logic by using new CONNECTED_PREFIX macro.
* ospf_interface.c: (ospf_if_is_configured, ospf_if_lookup_by_prefix,
ospf_if_lookup_recv_if) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_lsa.c: (lsa_link_ptop_set) Using the new CONNECTED_PREFIX
macro, both options collapse into the same code.
* ospf_snmp.c: (ospf_snmp_if_update) Simplify logic using new
CONNECTED_ID macro.
(ospf_snmp_is_if_have_addr) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_vty.c: (show_ip_ospf_interface_sub) Use new CONNECTED_PEER macro
instead of testing the IFF_POINTOPOINT flag.
* ospfd.c: (ospf_network_match_iface) Use new CONNECTED_PEER macro
instead of testing with if_is_pointopoint. And add commented-out
code to implement alternative (in my opinion) more elegant behavior
that has no special-case treatment for PtP addresses.
(ospf_network_run) Use new CONNECTED_ID macro to simplify logic.
* rip_interface.c: (rip_interface_multicast_set) Use new CONNECTED_ID
macro to simplify logic.
(rip_request_interface_send) Fix minor bug: ipv4_broadcast_addr does
not give a useful result if prefixlen is 32 (we require a peer
address in such cases).
* ripd.c: (rip_update_interface) Fix same bug as above.
2006-12-12 20:18:21 +01:00
|
|
|
flags = ZEBRA_IFA_PEER;
|
|
|
|
} else if (ifap->ifa_broadaddr
|
|
|
|
&& !IPV4_ADDR_SAME(
|
|
|
|
&addr->sin_addr,
|
|
|
|
&((struct sockaddr_in *)
|
|
|
|
ifap->ifa_broadaddr)
|
|
|
|
->sin_addr)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
dest = (struct sockaddr_in *)
|
|
|
|
ifap->ifa_broadaddr;
|
|
|
|
dest_pnt = &dest->sin_addr;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
[PtP over ethernet] New peer flag allows much more addressing flexibility
2006-12-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* if.h: (struct connected) Add new ZEBRA_IFA_PEER flag indicating
whether a peer address has been configured. Comment now shows
the new interpretation of the destination addr: if ZEBRA_IFA_PEER
is set, then it must contain the destination address, otherwise
it may contain the broadcast address or be NULL.
(CONNECTED_DEST_HOST,CONNECTED_POINTOPOINT_HOST) Remove obsolete
macros that were specific to IPv4 and not fully general.
(CONNECTED_PEER) New macro to check ZEBRA_IFA_PEER flag.
(CONNECTED_PREFIX) New macro giving the prefix to insert into
the RIB: if CONNECTED_PEER, then use the destination (peer) address,
else use the address field.
(CONNECTED_ID) New macro to come up with an identifying address
for the struct connected.
* if.c: (if_lookup_address, connected_lookup_address) Streamline
logic with new CONNECTED_PREFIX macro.
* prefix.h: (PREFIX_COPY_IPV4, PREFIX_COPY_IPV6) New macros
for better performance than the general prefix_copy function.
* zclient.c: (zebra_interface_address_read) For non-null destination
addresses, set prefixlen to equal the address prefixlen. This
is needed to get the new CONNECTED_PREFIX macro to work properly.
* connected.c: (connected_up_ipv4, connected_down_ipv4,
connected_up_ipv6, connected_down_ipv6) Simplify logic using the
new CONNECTED_PREFIX macro.
(connected_add_ipv4) Set prefixlen in destination addresses (required
by the CONNECTED_PREFIX macro). Use CONNECTED_PEER macro instead
of testing for IFF_POINTOPOINT. Delete invalid warning message.
Warn about cases where the ZEBRA_IFA_PEER is set but no
destination address has been supplied (and turn off the flag).
(connected_add_ipv6) Add new flags argument so callers may set
the ZEBRA_IFA_PEER flag. If peer/broadcast address satisfies
IN6_IS_ADDR_UNSPECIFIED, then reject it with a warning.
Set prefixlen in destination address so CONNECTED_PREFIX will work.
* connected.h: (connected_add_ipv6) Add new flags argument so
callers may set the ZEBRA_IFA_PEER flag.
* interface.c: (connected_dump_vty) Use CONNECTED_PEER macro
to decide whether the destination address is a peer or broadcast
address (instead of checking IFF_BROADCAST and IFF_POINTOPOINT).
* if_ioctl.c: (if_getaddrs) Instead of setting a peer address
only when the IFF_POINTOPOINT is set, we now accept a peer
address whenever it is available and not the same as the local
address. Otherwise (no peer address assigned), we check
for a broadcast address (regardless of the IFF_BROADCAST flag).
And must now pass a flags value of ZEBRA_IFA_PEER to
connected_add_ipv4 when a peer address is assigned.
The same new logic is used with the IPv6 code as well (and we
pass the new flags argument to connected_add_ipv6).
(if_get_addr) Do not bother to check IFF_POINTOPOINT: just
issue the SIOCGIFDSTADDR ioctl and see if we get back
a peer address not matching the local address (and set
the ZEBRA_IFA_PEER in that case). If there's no peer address,
try to grab SIOCGIFBRDADDR regardless of whether IFF_BROADCAST is set.
* if_ioctl_solaris.c: (if_get_addr) Just try the SIOCGLIFDSTADDR ioctl
without bothering to check the IFF_POINTOPOINT flag. And if
no peer address was found, just try the SIOCGLIFBRDADDR ioctl
without checking the IFF_BROADCAST flag. Call connected_add_ipv4
and connected_add_ipv6 with appropriate flags.
* if_proc.c: (ifaddr_proc_ipv6) Must pass new flags argument to
connected_add_ipv6.
* kernel_socket.c: (ifam_read) Must pass new flags argument to
connected_add_ipv6.
* rt_netlink.c: (netlink_interface_addr) Copy logic from iproute2
to determine local and possible peer address (so there's no longer
a test for IFF_POINTOPOINT). Set ZEBRA_IFA_PEER flag appropriately.
Pass new flags argument to connected_add_ipv6.
(netlink_address) Test !CONNECTED_PEER instead of if_is_broadcast
to determine whether the connected destination address is a
broadcast address.
* bgp_nexthop.c: (bgp_connected_add, bgp_connected_delete)
Simplify logic by using new CONNECTED_PREFIX macro.
* ospf_interface.c: (ospf_if_is_configured, ospf_if_lookup_by_prefix,
ospf_if_lookup_recv_if) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_lsa.c: (lsa_link_ptop_set) Using the new CONNECTED_PREFIX
macro, both options collapse into the same code.
* ospf_snmp.c: (ospf_snmp_if_update) Simplify logic using new
CONNECTED_ID macro.
(ospf_snmp_is_if_have_addr) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_vty.c: (show_ip_ospf_interface_sub) Use new CONNECTED_PEER macro
instead of testing the IFF_POINTOPOINT flag.
* ospfd.c: (ospf_network_match_iface) Use new CONNECTED_PEER macro
instead of testing with if_is_pointopoint. And add commented-out
code to implement alternative (in my opinion) more elegant behavior
that has no special-case treatment for PtP addresses.
(ospf_network_run) Use new CONNECTED_ID macro to simplify logic.
* rip_interface.c: (rip_interface_multicast_set) Use new CONNECTED_ID
macro to simplify logic.
(rip_request_interface_send) Fix minor bug: ipv4_broadcast_addr does
not give a useful result if prefixlen is 32 (we require a peer
address in such cases).
* ripd.c: (rip_update_interface) Fix same bug as above.
2006-12-12 20:18:21 +01:00
|
|
|
connected_add_ipv4(ifp, flags, &addr->sin_addr,
|
zebra: set connected route metric based on the devaddr metric
MACVLAN devices are typically used for applications such as VRR/VRRP that
require a second MAC address (virtual). These devices have a corresponding
SVI/VLAN device -
root@TORC11:~# ip addr show vlan1002
39: vlan1002@bridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9152 qdisc noqueue master vrf1 state UP group default
link/ether 00:02:00:00:00:2e brd ff:ff:ff:ff:ff:ff
inet6 2001:aa:1::2/64 scope global
valid_lft forever preferred_lft forever
root@TORC11:~# ip addr show vlan1002-v0
40: vlan1002-v0@vlan1002: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9152 qdisc noqueue master vrf1 state UP group default
link/ether 00:00:5e:00:01:01 brd ff:ff:ff:ff:ff:ff
inet6 2001:aa:1::a/64 metric 1024 scope global
valid_lft forever preferred_lft forever
root@TORC11:~#
The macvlan device is used primarily for RX (VR-IP/VR-MAC). And TX is via
the SVI. To acheive that functionality the macvlan network's metric
is set to a higher value.
Zebra currently ignores the devaddr metric sent by the kernel and hardcodes
it to 0. This commit eliminates that hardcoding. If the devaddr metric
is available (METRIC_MAX) it is used for setting up the connected route
otherwise we fallback to the dev/interface metric.
Setting the macvlan metric to a higher value ensures that zebra will always
select the connected route on the SVI (and subsequently use it for next hop
resolution etc.) -
root@TORC11:~# vtysh -c "show ip route vrf vrf1 2001:aa:1::/64"
Routing entry for 2001:aa:1::/64
Known via "connected", distance 0, metric 1024, vrf vrf1
Last update 11:30:56 ago
* directly connected, vlan1002-v0
Routing entry for 2001:aa:1::/64
Known via "connected", distance 0, metric 0, vrf vrf1, best
Last update 11:30:56 ago
* directly connected, vlan1002
root@TORC11:~#
Ticket: CM-23511
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-01-15 00:45:33 +01:00
|
|
|
prefixlen, dest_pnt, NULL,
|
|
|
|
METRIC_MAX);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
if (ifap->ifa_addr->sa_family == AF_INET6) {
|
|
|
|
struct sockaddr_in6 *addr;
|
|
|
|
struct sockaddr_in6 *mask;
|
[PtP over ethernet] New peer flag allows much more addressing flexibility
2006-12-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* if.h: (struct connected) Add new ZEBRA_IFA_PEER flag indicating
whether a peer address has been configured. Comment now shows
the new interpretation of the destination addr: if ZEBRA_IFA_PEER
is set, then it must contain the destination address, otherwise
it may contain the broadcast address or be NULL.
(CONNECTED_DEST_HOST,CONNECTED_POINTOPOINT_HOST) Remove obsolete
macros that were specific to IPv4 and not fully general.
(CONNECTED_PEER) New macro to check ZEBRA_IFA_PEER flag.
(CONNECTED_PREFIX) New macro giving the prefix to insert into
the RIB: if CONNECTED_PEER, then use the destination (peer) address,
else use the address field.
(CONNECTED_ID) New macro to come up with an identifying address
for the struct connected.
* if.c: (if_lookup_address, connected_lookup_address) Streamline
logic with new CONNECTED_PREFIX macro.
* prefix.h: (PREFIX_COPY_IPV4, PREFIX_COPY_IPV6) New macros
for better performance than the general prefix_copy function.
* zclient.c: (zebra_interface_address_read) For non-null destination
addresses, set prefixlen to equal the address prefixlen. This
is needed to get the new CONNECTED_PREFIX macro to work properly.
* connected.c: (connected_up_ipv4, connected_down_ipv4,
connected_up_ipv6, connected_down_ipv6) Simplify logic using the
new CONNECTED_PREFIX macro.
(connected_add_ipv4) Set prefixlen in destination addresses (required
by the CONNECTED_PREFIX macro). Use CONNECTED_PEER macro instead
of testing for IFF_POINTOPOINT. Delete invalid warning message.
Warn about cases where the ZEBRA_IFA_PEER is set but no
destination address has been supplied (and turn off the flag).
(connected_add_ipv6) Add new flags argument so callers may set
the ZEBRA_IFA_PEER flag. If peer/broadcast address satisfies
IN6_IS_ADDR_UNSPECIFIED, then reject it with a warning.
Set prefixlen in destination address so CONNECTED_PREFIX will work.
* connected.h: (connected_add_ipv6) Add new flags argument so
callers may set the ZEBRA_IFA_PEER flag.
* interface.c: (connected_dump_vty) Use CONNECTED_PEER macro
to decide whether the destination address is a peer or broadcast
address (instead of checking IFF_BROADCAST and IFF_POINTOPOINT).
* if_ioctl.c: (if_getaddrs) Instead of setting a peer address
only when the IFF_POINTOPOINT is set, we now accept a peer
address whenever it is available and not the same as the local
address. Otherwise (no peer address assigned), we check
for a broadcast address (regardless of the IFF_BROADCAST flag).
And must now pass a flags value of ZEBRA_IFA_PEER to
connected_add_ipv4 when a peer address is assigned.
The same new logic is used with the IPv6 code as well (and we
pass the new flags argument to connected_add_ipv6).
(if_get_addr) Do not bother to check IFF_POINTOPOINT: just
issue the SIOCGIFDSTADDR ioctl and see if we get back
a peer address not matching the local address (and set
the ZEBRA_IFA_PEER in that case). If there's no peer address,
try to grab SIOCGIFBRDADDR regardless of whether IFF_BROADCAST is set.
* if_ioctl_solaris.c: (if_get_addr) Just try the SIOCGLIFDSTADDR ioctl
without bothering to check the IFF_POINTOPOINT flag. And if
no peer address was found, just try the SIOCGLIFBRDADDR ioctl
without checking the IFF_BROADCAST flag. Call connected_add_ipv4
and connected_add_ipv6 with appropriate flags.
* if_proc.c: (ifaddr_proc_ipv6) Must pass new flags argument to
connected_add_ipv6.
* kernel_socket.c: (ifam_read) Must pass new flags argument to
connected_add_ipv6.
* rt_netlink.c: (netlink_interface_addr) Copy logic from iproute2
to determine local and possible peer address (so there's no longer
a test for IFF_POINTOPOINT). Set ZEBRA_IFA_PEER flag appropriately.
Pass new flags argument to connected_add_ipv6.
(netlink_address) Test !CONNECTED_PEER instead of if_is_broadcast
to determine whether the connected destination address is a
broadcast address.
* bgp_nexthop.c: (bgp_connected_add, bgp_connected_delete)
Simplify logic by using new CONNECTED_PREFIX macro.
* ospf_interface.c: (ospf_if_is_configured, ospf_if_lookup_by_prefix,
ospf_if_lookup_recv_if) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_lsa.c: (lsa_link_ptop_set) Using the new CONNECTED_PREFIX
macro, both options collapse into the same code.
* ospf_snmp.c: (ospf_snmp_if_update) Simplify logic using new
CONNECTED_ID macro.
(ospf_snmp_is_if_have_addr) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_vty.c: (show_ip_ospf_interface_sub) Use new CONNECTED_PEER macro
instead of testing the IFF_POINTOPOINT flag.
* ospfd.c: (ospf_network_match_iface) Use new CONNECTED_PEER macro
instead of testing with if_is_pointopoint. And add commented-out
code to implement alternative (in my opinion) more elegant behavior
that has no special-case treatment for PtP addresses.
(ospf_network_run) Use new CONNECTED_ID macro to simplify logic.
* rip_interface.c: (rip_interface_multicast_set) Use new CONNECTED_ID
macro to simplify logic.
(rip_request_interface_send) Fix minor bug: ipv4_broadcast_addr does
not give a useful result if prefixlen is 32 (we require a peer
address in such cases).
* ripd.c: (rip_update_interface) Fix same bug as above.
2006-12-12 20:18:21 +01:00
|
|
|
int flags = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
addr = (struct sockaddr_in6 *)ifap->ifa_addr;
|
|
|
|
mask = (struct sockaddr_in6 *)ifap->ifa_netmask;
|
|
|
|
prefixlen = ip6_masklen(mask->sin6_addr);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 22:19:02 +01:00
|
|
|
#if defined(KAME)
|
|
|
|
if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
|
|
|
|
addr->sin6_scope_id =
|
2018-03-27 21:13:34 +02:00
|
|
|
ntohs(*(uint16_t *)&addr->sin6_addr
|
2002-12-13 22:19:02 +01:00
|
|
|
.s6_addr[2]);
|
|
|
|
addr->sin6_addr.s6_addr[2] =
|
|
|
|
addr->sin6_addr.s6_addr[3] = 0;
|
|
|
|
}
|
|
|
|
#endif
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-04-15 16:57:19 +02:00
|
|
|
connected_add_ipv6(ifp, flags, &addr->sin6_addr, NULL,
|
zebra: set connected route metric based on the devaddr metric
MACVLAN devices are typically used for applications such as VRR/VRRP that
require a second MAC address (virtual). These devices have a corresponding
SVI/VLAN device -
root@TORC11:~# ip addr show vlan1002
39: vlan1002@bridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9152 qdisc noqueue master vrf1 state UP group default
link/ether 00:02:00:00:00:2e brd ff:ff:ff:ff:ff:ff
inet6 2001:aa:1::2/64 scope global
valid_lft forever preferred_lft forever
root@TORC11:~# ip addr show vlan1002-v0
40: vlan1002-v0@vlan1002: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9152 qdisc noqueue master vrf1 state UP group default
link/ether 00:00:5e:00:01:01 brd ff:ff:ff:ff:ff:ff
inet6 2001:aa:1::a/64 metric 1024 scope global
valid_lft forever preferred_lft forever
root@TORC11:~#
The macvlan device is used primarily for RX (VR-IP/VR-MAC). And TX is via
the SVI. To acheive that functionality the macvlan network's metric
is set to a higher value.
Zebra currently ignores the devaddr metric sent by the kernel and hardcodes
it to 0. This commit eliminates that hardcoding. If the devaddr metric
is available (METRIC_MAX) it is used for setting up the connected route
otherwise we fallback to the dev/interface metric.
Setting the macvlan metric to a higher value ensures that zebra will always
select the connected route on the SVI (and subsequently use it for next hop
resolution etc.) -
root@TORC11:~# vtysh -c "show ip route vrf vrf1 2001:aa:1::/64"
Routing entry for 2001:aa:1::/64
Known via "connected", distance 0, metric 1024, vrf vrf1
Last update 11:30:56 ago
* directly connected, vlan1002-v0
Routing entry for 2001:aa:1::/64
Known via "connected", distance 0, metric 0, vrf vrf1, best
Last update 11:30:56 ago
* directly connected, vlan1002
root@TORC11:~#
Ticket: CM-23511
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-01-15 00:45:33 +01:00
|
|
|
prefixlen, NULL, METRIC_MAX);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
freeifaddrs(ifapfree);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fetch interface information via ioctl(). */
|
|
|
|
static void interface_info_ioctl()
|
|
|
|
{
|
2017-10-03 03:06:01 +02:00
|
|
|
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
2002-12-13 21:15:29 +01:00
|
|
|
struct interface *ifp;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-10-06 20:25:58 +02:00
|
|
|
FOR_ALL_INTERFACES (vrf, ifp) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if_get_index(ifp);
|
|
|
|
#ifdef SIOCGIFHWADDR
|
|
|
|
if_get_hwaddr(ifp);
|
|
|
|
#endif /* SIOCGIFHWADDR */
|
|
|
|
if_get_flags(ifp);
|
|
|
|
if_get_mtu(ifp);
|
|
|
|
if_get_metric(ifp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Lookup all interface information. */
|
2016-02-01 19:55:42 +01:00
|
|
|
void interface_list(struct zebra_ns *zns)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-02-01 19:55:42 +01:00
|
|
|
|
2022-09-13 08:28:35 +02:00
|
|
|
zlog_info("%s: NS %u", __func__, zns->ns_id);
|
2016-02-01 19:55:42 +01:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Linux can do both proc & ioctl, ioctl is the only way to get
|
|
|
|
interface aliases in 2.2 series kernels. */
|
|
|
|
#ifdef HAVE_PROC_NET_DEV
|
|
|
|
interface_list_proc();
|
|
|
|
#endif /* HAVE_PROC_NET_DEV */
|
|
|
|
interface_list_ioctl();
|
|
|
|
|
|
|
|
/* After listing is done, get index, address, flags and other
|
|
|
|
interface's information. */
|
|
|
|
interface_info_ioctl();
|
|
|
|
|
|
|
|
if_getaddrs();
|
|
|
|
|
2017-01-13 13:57:57 +01:00
|
|
|
#if defined(HAVE_PROC_NET_IF_INET6)
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Linux provides interface's IPv6 address via
|
|
|
|
/proc/net/if_inet6. */
|
|
|
|
ifaddr_proc_ipv6();
|
2017-01-13 13:57:57 +01:00
|
|
|
#endif /* HAVE_PROC_NET_IF_INET6 */
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-26 19:49:15 +02:00
|
|
|
|
|
|
|
#endif /* OPEN_BSD */
|