summaryrefslogtreecommitdiffstats
path: root/zebra/if_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/if_ioctl.c')
-rw-r--r--zebra/if_ioctl.c487
1 files changed, 237 insertions, 250 deletions
diff --git a/zebra/if_ioctl.c b/zebra/if_ioctl.c
index 73da04965..2d5d604a8 100644
--- a/zebra/if_ioctl.c
+++ b/zebra/if_ioctl.c
@@ -38,306 +38,293 @@
#include <ifaddrs.h>
/* Interface looking up using infamous SIOCGIFCONF. */
-static int
-interface_list_ioctl (void)
+static int interface_list_ioctl(void)
{
- int ret;
- int sock;
+ int ret;
+ int sock;
#define IFNUM_BASE 32
- int ifnum;
- struct ifreq *ifreq;
- struct ifconf ifconf;
- struct interface *ifp;
- int n;
- int lastlen;
-
- /* Normally SIOCGIFCONF works with AF_INET socket. */
- sock = socket (AF_INET, SOCK_DGRAM, 0);
- if (sock < 0)
- {
- zlog_warn ("Can't make AF_INET socket stream: %s", safe_strerror (errno));
- return -1;
- }
-
- /* Set initial ifreq count. This will be double when SIOCGIFCONF
- fail. Solaris has SIOCGIFNUM. */
+ int ifnum;
+ struct ifreq *ifreq;
+ struct ifconf ifconf;
+ struct interface *ifp;
+ int n;
+ int lastlen;
+
+ /* Normally SIOCGIFCONF works with AF_INET socket. */
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock < 0) {
+ zlog_warn("Can't make AF_INET socket stream: %s",
+ safe_strerror(errno));
+ return -1;
+ }
+
+/* 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++;
+ ret = ioctl(sock, SIOCGIFNUM, &ifnum);
+ if (ret < 0)
+ ifnum = IFNUM_BASE;
+ else
+ ifnum++;
#else
- ifnum = IFNUM_BASE;
+ ifnum = IFNUM_BASE;
#endif /* SIOCGIFNUM */
- ifconf.ifc_buf = NULL;
-
- 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);
-
- ret = ioctl(sock, SIOCGIFCONF, &ifconf);
-
- if (ret < 0)
- {
- zlog_warn ("SIOCGIFCONF: %s", safe_strerror(errno));
- goto end;
- }
- /* Repeatedly get info til buffer fails to grow. */
- if (ifconf.ifc_len > lastlen)
- {
- lastlen = ifconf.ifc_len;
- ifnum += 10;
- continue;
+ ifconf.ifc_buf = NULL;
+
+ 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);
+
+ ret = ioctl(sock, SIOCGIFCONF, &ifconf);
+
+ if (ret < 0) {
+ zlog_warn("SIOCGIFCONF: %s", safe_strerror(errno));
+ goto end;
+ }
+ /* Repeatedly get info til buffer fails to grow. */
+ if (ifconf.ifc_len > lastlen) {
+ lastlen = ifconf.ifc_len;
+ ifnum += 10;
+ continue;
+ }
+ /* Success. */
+ break;
}
- /* Success. */
- break;
- }
- /* Allocate interface. */
- ifreq = ifconf.ifc_req;
+ /* Allocate interface. */
+ ifreq = ifconf.ifc_req;
#ifdef OPEN_BSD
- for (n = 0; n < ifconf.ifc_len; )
- {
- unsigned int size;
-
- ifreq = (struct ifreq *)((caddr_t) ifconf.ifc_req + n);
- ifp = if_get_by_name_len(ifreq->ifr_name,
- strnlen(ifreq->ifr_name,
- sizeof(ifreq->ifr_name)),
- VRF_DEFAULT, 0);
- 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;
- }
+ for (n = 0; n < ifconf.ifc_len;) {
+ unsigned int size;
+
+ ifreq = (struct ifreq *)((caddr_t)ifconf.ifc_req + n);
+ ifp = if_get_by_name_len(
+ ifreq->ifr_name,
+ strnlen(ifreq->ifr_name, sizeof(ifreq->ifr_name)),
+ VRF_DEFAULT, 0);
+ 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))
- {
- ifp = if_get_by_name_len(ifreq->ifr_name,
- strnlen(ifreq->ifr_name,
- sizeof(ifreq->ifr_name)),
- VRF_DEFAULT, 0);
- if_add_update (ifp);
- ifreq++;
- }
+ for (n = 0; n < ifconf.ifc_len; n += sizeof(struct ifreq)) {
+ ifp = if_get_by_name_len(
+ ifreq->ifr_name,
+ strnlen(ifreq->ifr_name, sizeof(ifreq->ifr_name)),
+ VRF_DEFAULT, 0);
+ if_add_update(ifp);
+ ifreq++;
+ }
#endif /* OPEN_BSD */
- end:
- close (sock);
- XFREE (MTYPE_TMP, ifconf.ifc_buf);
+end:
+ close(sock);
+ XFREE(MTYPE_TMP, ifconf.ifc_buf);
- return ret;
+ return ret;
}
/* Get interface's index by ioctl. */
-static int
-if_get_index (struct interface *ifp)
+static int if_get_index(struct interface *ifp)
{
- ifp->ifindex = if_nametoindex(ifp->name);
- return ifp->ifindex;
+ ifp->ifindex = if_nametoindex(ifp->name);
+ return ifp->ifindex;
}
#ifdef SIOCGIFHWADDR
-static int
-if_get_hwaddr (struct interface *ifp)
+static int if_get_hwaddr(struct interface *ifp)
{
- int ret;
- struct ifreq ifreq;
- int i;
-
- strncpy (ifreq.ifr_name, ifp->name, IFNAMSIZ);
- ifreq.ifr_addr.sa_family = AF_INET;
-
- /* Fetch Hardware address if available. */
- ret = if_ioctl (SIOCGIFHWADDR, (caddr_t) &ifreq);
- if (ret < 0)
- ifp->hw_addr_len = 0;
- else
- {
- memcpy (ifp->hw_addr, ifreq.ifr_hwaddr.sa_data, 6);
-
- for (i = 0; i < 6; i++)
- if (ifp->hw_addr[i] != 0)
- break;
-
- if (i == 6)
- ifp->hw_addr_len = 0;
- else
- ifp->hw_addr_len = 6;
- }
- return 0;
+ int ret;
+ struct ifreq ifreq;
+ int i;
+
+ strncpy(ifreq.ifr_name, ifp->name, IFNAMSIZ);
+ ifreq.ifr_addr.sa_family = AF_INET;
+
+ /* Fetch Hardware address if available. */
+ ret = if_ioctl(SIOCGIFHWADDR, (caddr_t)&ifreq);
+ if (ret < 0)
+ ifp->hw_addr_len = 0;
+ else {
+ memcpy(ifp->hw_addr, ifreq.ifr_hwaddr.sa_data, 6);
+
+ for (i = 0; i < 6; i++)
+ if (ifp->hw_addr[i] != 0)
+ break;
+
+ if (i == 6)
+ ifp->hw_addr_len = 0;
+ else
+ ifp->hw_addr_len = 6;
+ }
+ return 0;
}
#endif /* SIOCGIFHWADDR */
-static int
-if_getaddrs (void)
+static int if_getaddrs(void)
{
- int ret;
- struct ifaddrs *ifap;
- struct ifaddrs *ifapfree;
- struct interface *ifp;
- int prefixlen;
-
- ret = getifaddrs (&ifap);
- if (ret != 0)
- {
- zlog_err ("getifaddrs(): %s", safe_strerror (errno));
- return -1;
- }
-
- for (ifapfree = ifap; ifap; ifap = ifap->ifa_next)
- {
- if (ifap->ifa_addr == NULL)
- {
- zlog_err ("%s: nonsensical ifaddr with NULL ifa_addr, ifname %s",
- __func__, (ifap->ifa_name ? ifap->ifa_name : "(null)"));
- continue;
- }
-
- ifp = if_lookup_by_name (ifap->ifa_name, VRF_DEFAULT);
- if (ifp == NULL)
- {
- zlog_err ("if_getaddrs(): Can't lookup interface %s\n",
- ifap->ifa_name);
- continue;
+ int ret;
+ struct ifaddrs *ifap;
+ struct ifaddrs *ifapfree;
+ struct interface *ifp;
+ int prefixlen;
+
+ ret = getifaddrs(&ifap);
+ if (ret != 0) {
+ zlog_err("getifaddrs(): %s", safe_strerror(errno));
+ return -1;
}
- if (ifap->ifa_addr->sa_family == AF_INET)
- {
- struct sockaddr_in *addr;
- struct sockaddr_in *mask;
- struct sockaddr_in *dest;
- struct in_addr *dest_pnt;
- int flags = 0;
-
- addr = (struct sockaddr_in *) ifap->ifa_addr;
- mask = (struct sockaddr_in *) ifap->ifa_netmask;
- prefixlen = ip_masklen (mask->sin_addr);
-
- dest_pnt = NULL;
-
- if (ifap->ifa_dstaddr &&
- !IPV4_ADDR_SAME(&addr->sin_addr,
- &((struct sockaddr_in *)
- ifap->ifa_dstaddr)->sin_addr))
- {
- dest = (struct sockaddr_in *) ifap->ifa_dstaddr;
- dest_pnt = &dest->sin_addr;
- flags = ZEBRA_IFA_PEER;
- }
- else if (ifap->ifa_broadaddr &&
- !IPV4_ADDR_SAME(&addr->sin_addr,
- &((struct sockaddr_in *)
- ifap->ifa_broadaddr)->sin_addr))
- {
- dest = (struct sockaddr_in *) ifap->ifa_broadaddr;
- dest_pnt = &dest->sin_addr;
- }
-
- connected_add_ipv4 (ifp, flags, &addr->sin_addr,
- prefixlen, dest_pnt, NULL);
- }
- if (ifap->ifa_addr->sa_family == AF_INET6)
- {
- struct sockaddr_in6 *addr;
- struct sockaddr_in6 *mask;
- struct sockaddr_in6 *dest;
- struct in6_addr *dest_pnt;
- int flags = 0;
-
- addr = (struct sockaddr_in6 *) ifap->ifa_addr;
- mask = (struct sockaddr_in6 *) ifap->ifa_netmask;
- prefixlen = ip6_masklen (mask->sin6_addr);
-
- dest_pnt = NULL;
-
- if (ifap->ifa_dstaddr &&
- !IPV6_ADDR_SAME(&addr->sin6_addr,
- &((struct sockaddr_in6 *)
- ifap->ifa_dstaddr)->sin6_addr))
- {
- dest = (struct sockaddr_in6 *) ifap->ifa_dstaddr;
- dest_pnt = &dest->sin6_addr;
- flags = ZEBRA_IFA_PEER;
- }
- else if (ifap->ifa_broadaddr &&
- !IPV6_ADDR_SAME(&addr->sin6_addr,
- &((struct sockaddr_in6 *)
- ifap->ifa_broadaddr)->sin6_addr))
- {
- dest = (struct sockaddr_in6 *) ifap->ifa_broadaddr;
- dest_pnt = &dest->sin6_addr;
- }
+ for (ifapfree = ifap; ifap; ifap = ifap->ifa_next) {
+ if (ifap->ifa_addr == NULL) {
+ zlog_err(
+ "%s: nonsensical ifaddr with NULL ifa_addr, ifname %s",
+ __func__,
+ (ifap->ifa_name ? ifap->ifa_name : "(null)"));
+ continue;
+ }
+
+ ifp = if_lookup_by_name(ifap->ifa_name, VRF_DEFAULT);
+ if (ifp == NULL) {
+ zlog_err("if_getaddrs(): Can't lookup interface %s\n",
+ ifap->ifa_name);
+ continue;
+ }
+
+ if (ifap->ifa_addr->sa_family == AF_INET) {
+ struct sockaddr_in *addr;
+ struct sockaddr_in *mask;
+ struct sockaddr_in *dest;
+ struct in_addr *dest_pnt;
+ int flags = 0;
+
+ addr = (struct sockaddr_in *)ifap->ifa_addr;
+ mask = (struct sockaddr_in *)ifap->ifa_netmask;
+ prefixlen = ip_masklen(mask->sin_addr);
+
+ dest_pnt = NULL;
+
+ if (ifap->ifa_dstaddr
+ && !IPV4_ADDR_SAME(&addr->sin_addr,
+ &((struct sockaddr_in *)
+ ifap->ifa_dstaddr)
+ ->sin_addr)) {
+ dest = (struct sockaddr_in *)ifap->ifa_dstaddr;
+ dest_pnt = &dest->sin_addr;
+ flags = ZEBRA_IFA_PEER;
+ } else if (ifap->ifa_broadaddr
+ && !IPV4_ADDR_SAME(
+ &addr->sin_addr,
+ &((struct sockaddr_in *)
+ ifap->ifa_broadaddr)
+ ->sin_addr)) {
+ dest = (struct sockaddr_in *)
+ ifap->ifa_broadaddr;
+ dest_pnt = &dest->sin_addr;
+ }
+
+ connected_add_ipv4(ifp, flags, &addr->sin_addr,
+ prefixlen, dest_pnt, NULL);
+ }
+ if (ifap->ifa_addr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *addr;
+ struct sockaddr_in6 *mask;
+ struct sockaddr_in6 *dest;
+ struct in6_addr *dest_pnt;
+ int flags = 0;
+
+ addr = (struct sockaddr_in6 *)ifap->ifa_addr;
+ mask = (struct sockaddr_in6 *)ifap->ifa_netmask;
+ prefixlen = ip6_masklen(mask->sin6_addr);
+
+ dest_pnt = NULL;
+
+ if (ifap->ifa_dstaddr
+ && !IPV6_ADDR_SAME(&addr->sin6_addr,
+ &((struct sockaddr_in6 *)
+ ifap->ifa_dstaddr)
+ ->sin6_addr)) {
+ dest = (struct sockaddr_in6 *)ifap->ifa_dstaddr;
+ dest_pnt = &dest->sin6_addr;
+ flags = ZEBRA_IFA_PEER;
+ } else if (ifap->ifa_broadaddr
+ && !IPV6_ADDR_SAME(
+ &addr->sin6_addr,
+ &((struct sockaddr_in6 *)
+ ifap->ifa_broadaddr)
+ ->sin6_addr)) {
+ dest = (struct sockaddr_in6 *)
+ ifap->ifa_broadaddr;
+ dest_pnt = &dest->sin6_addr;
+ }
#if defined(KAME)
- if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr))
- {
- addr->sin6_scope_id =
- ntohs(*(u_int16_t *)&addr->sin6_addr.s6_addr[2]);
- addr->sin6_addr.s6_addr[2] = addr->sin6_addr.s6_addr[3] = 0;
- }
-#endif
-
- connected_add_ipv6 (ifp, flags, &addr->sin6_addr, prefixlen,
- dest_pnt, NULL);
+ if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
+ addr->sin6_scope_id =
+ ntohs(*(u_int16_t *)&addr->sin6_addr
+ .s6_addr[2]);
+ addr->sin6_addr.s6_addr[2] =
+ addr->sin6_addr.s6_addr[3] = 0;
+ }
+#endif
+
+ connected_add_ipv6(ifp, flags, &addr->sin6_addr,
+ prefixlen, dest_pnt, NULL);
+ }
}
- }
- freeifaddrs (ifapfree);
+ freeifaddrs(ifapfree);
- return 0;
+ return 0;
}
/* Fetch interface information via ioctl(). */
-static void
-interface_info_ioctl ()
+static void interface_info_ioctl()
{
- struct listnode *node, *nnode;
- struct interface *ifp;
-
- for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), node, nnode, ifp))
- {
- if_get_index (ifp);
+ struct listnode *node, *nnode;
+ struct interface *ifp;
+
+ for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) {
+ if_get_index(ifp);
#ifdef SIOCGIFHWADDR
- if_get_hwaddr (ifp);
+ if_get_hwaddr(ifp);
#endif /* SIOCGIFHWADDR */
- if_get_flags (ifp);
- if_get_mtu (ifp);
- if_get_metric (ifp);
- }
+ if_get_flags(ifp);
+ if_get_mtu(ifp);
+ if_get_metric(ifp);
+ }
}
/* Lookup all interface information. */
-void
-interface_list (struct zebra_ns *zns)
+void interface_list(struct zebra_ns *zns)
{
- zlog_info ("interface_list: NS %u", zns->ns_id);
+ zlog_info("interface_list: NS %u", zns->ns_id);
- /* Linux can do both proc & ioctl, ioctl is the only way to get
- interface aliases in 2.2 series kernels. */
+/* 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 ();
+ interface_list_proc();
#endif /* HAVE_PROC_NET_DEV */
- interface_list_ioctl ();
+ interface_list_ioctl();
- /* After listing is done, get index, address, flags and other
- interface's information. */
- interface_info_ioctl ();
+ /* After listing is done, get index, address, flags and other
+ interface's information. */
+ interface_info_ioctl();
- if_getaddrs ();
+ if_getaddrs();
#if defined(HAVE_PROC_NET_IF_INET6)
- /* Linux provides interface's IPv6 address via
- /proc/net/if_inet6. */
- ifaddr_proc_ipv6 ();
+ /* Linux provides interface's IPv6 address via
+ /proc/net/if_inet6. */
+ ifaddr_proc_ipv6();
#endif /* HAVE_PROC_NET_IF_INET6 */
}