]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/if_ioctl_solaris.c
Merge pull request #3503 from qlyoung/fix-bgpd-show-ip-neigh-json-double-free
[mirror_frr.git] / zebra / if_ioctl_solaris.c
index 905ac619c69041341df2c35767bdbd5c1044e262..0206d4938efda498eb908772f28b574a8cb56396 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <zebra.h>
 
+#ifdef SUNOS_5
+
 #include "if.h"
 #include "sockunion.h"
 #include "prefix.h"
 #include "privs.h"
 #include "vrf.h"
 #include "vty.h"
+#include "lib_errors.h"
 
 #include "zebra/interface.h"
 #include "zebra/ioctl_solaris.h"
 #include "zebra/rib.h"
+#include "zebra/rt.h"
+#include "zebra/zebra_errors.h"
 
 static int if_get_addr(struct interface *, struct sockaddr *, const char *);
 static void interface_info_ioctl(struct interface *);
@@ -53,37 +57,32 @@ static int interface_list_ioctl(int af)
        struct lifconf lifconf;
        struct interface *ifp;
        int n;
-       int save_errno;
        size_t needed, lastneeded = 0;
        char *buf = NULL;
 
-       if (zserv_privs.change(ZPRIVS_RAISE))
-               zlog_err("Can't raise privileges");
+       frr_elevate_privs(&zserv_privs) {
+               sock = socket(af, SOCK_DGRAM, 0);
+       }
 
-       sock = socket(af, SOCK_DGRAM, 0);
        if (sock < 0) {
-               zlog_warn("Can't make %s socket stream: %s",
-                         (af == AF_INET ? "AF_INET" : "AF_INET6"),
-                         safe_strerror(errno));
-
-               if (zserv_privs.change(ZPRIVS_LOWER))
-                       zlog_err("Can't lower privileges");
-
+               flog_err_sys(EC_LIB_SOCKET, "Can't make %s socket stream: %s",
+                            (af == AF_INET ? "AF_INET" : "AF_INET6"),
+                            safe_strerror(errno));
                return -1;
        }
 
-calculate_lifc_len: /* must hold privileges to enter here */
-       lifn.lifn_family = af;
-       lifn.lifn_flags = LIFC_NOXMIT; /* we want NOXMIT interfaces too */
-       ret = ioctl(sock, SIOCGLIFNUM, &lifn);
-       save_errno = errno;
-
-       if (zserv_privs.change(ZPRIVS_LOWER))
-               zlog_err("Can't lower privileges");
+calculate_lifc_len:
+       frr_elevate_privs(&zserv_privs) {
+               lifn.lifn_family = af;
+               lifn.lifn_flags = LIFC_NOXMIT;
+               /* we want NOXMIT interfaces too */
+               ret = ioctl(sock, SIOCGLIFNUM, &lifn);
+       }
 
        if (ret < 0) {
-               zlog_warn("interface_list_ioctl: SIOCGLIFNUM failed %s",
-                         safe_strerror(save_errno));
+               flog_err_sys(EC_LIB_SYSTEM_CALL,
+                            "interface_list_ioctl: SIOCGLIFNUM failed %s",
+                            safe_strerror(errno));
                close(sock);
                return -1;
        }
@@ -99,11 +98,7 @@ calculate_lifc_len: /* must hold privileges to enter here */
        if (needed > lastneeded || needed < lastneeded / 2) {
                if (buf != NULL)
                        XFREE(MTYPE_TMP, buf);
-               if ((buf = XMALLOC(MTYPE_TMP, needed)) == NULL) {
-                       zlog_warn("interface_list_ioctl: malloc failed");
-                       close(sock);
-                       return -1;
-               }
+               buf = XMALLOC(MTYPE_TMP, needed);
        }
        lastneeded = needed;
 
@@ -112,27 +107,19 @@ calculate_lifc_len: /* must hold privileges to enter here */
        lifconf.lifc_len = needed;
        lifconf.lifc_buf = buf;
 
-       if (zserv_privs.change(ZPRIVS_RAISE))
-               zlog_err("Can't raise privileges");
-
-       ret = ioctl(sock, SIOCGLIFCONF, &lifconf);
+       frr_elevate_privs(&zserv_privs) {
+               ret = ioctl(sock, SIOCGLIFCONF, &lifconf);
+       }
 
        if (ret < 0) {
                if (errno == EINVAL)
-                       goto calculate_lifc_len; /* deliberately hold privileges
-                                                   */
-
-               zlog_warn("SIOCGLIFCONF: %s", safe_strerror(errno));
-
-               if (zserv_privs.change(ZPRIVS_LOWER))
-                       zlog_err("Can't lower privileges");
+                       goto calculate_lifc_len;
 
+               flog_err_sys(EC_LIB_SYSTEM_CALL, "SIOCGLIFCONF: %s",
+                            safe_strerror(errno));
                goto end;
        }
 
-       if (zserv_privs.change(ZPRIVS_LOWER))
-               zlog_err("Can't lower privileges");
-
        /* Allocate interface. */
        lifreq = lifconf.lifc_req;
 
@@ -169,8 +156,7 @@ calculate_lifc_len: /* must hold privileges to enter here */
                       && (*(lifreq->lifr_name + normallen) != ':'))
                        normallen++;
 
-               ifp = if_get_by_name_len(lifreq->lifr_name, normallen,
-                                        VRF_DEFAULT, 0);
+               ifp = if_get_by_name(lifreq->lifr_name, VRF_DEFAULT);
 
                if (lifreq->lifr_addr.ss_family == AF_INET)
                        ifp->flags |= IFF_IPV4;
@@ -221,15 +207,16 @@ static int if_get_index(struct interface *ifp)
                ret = -1;
 
        if (ret < 0) {
-               zlog_warn("SIOCGLIFINDEX(%s) failed", ifp->name);
+               flog_err_sys(EC_LIB_SYSTEM_CALL, "SIOCGLIFINDEX(%s) failed",
+                            ifp->name);
                return ret;
        }
 
 /* OK we got interface index. */
 #ifdef ifr_ifindex
-       ifp->ifindex = lifreq.lifr_ifindex;
+       if_set_index(ifp, lifreq.lifr_ifindex);
 #else
-       ifp->ifindex = lifreq.lifr_index;
+       if_set_index(ifp, lifreq.lifr_index);
 #endif
        return ifp->ifindex;
 }
@@ -252,7 +239,7 @@ static int if_get_addr(struct interface *ifp, struct sockaddr *addr,
        struct lifreq lifreq;
        struct sockaddr_storage mask, dest;
        char *dest_pnt = NULL;
-       u_char prefixlen = 0;
+       uint8_t prefixlen = 0;
        afi_t af;
        int flags = 0;
 
@@ -283,8 +270,9 @@ static int if_get_addr(struct interface *ifp, struct sockaddr *addr,
 
                if (ret < 0) {
                        if (errno != EADDRNOTAVAIL) {
-                               zlog_warn("SIOCGLIFNETMASK (%s) fail: %s",
-                                         ifp->name, safe_strerror(errno));
+                               flog_err_sys(EC_LIB_SYSTEM_CALL,
+                                            "SIOCGLIFNETMASK (%s) fail: %s",
+                                            ifp->name, safe_strerror(errno));
                                return ret;
                        }
                        return 0;
@@ -303,8 +291,9 @@ static int if_get_addr(struct interface *ifp, struct sockaddr *addr,
                        if (ifp->flags & IFF_POINTOPOINT)
                                prefixlen = IPV6_MAX_BITLEN;
                        else
-                               zlog_warn("SIOCGLIFSUBNET (%s) fail: %s",
-                                         ifp->name, safe_strerror(errno));
+                               flog_err_sys(EC_LIB_SYSTEM_CALL,
+                                            "SIOCGLIFSUBNET (%s) fail: %s",
+                                            ifp->name, safe_strerror(errno));
                } else {
                        prefixlen = lifreq.lifr_addrlen;
                }
@@ -315,9 +304,8 @@ static int if_get_addr(struct interface *ifp, struct sockaddr *addr,
                connected_add_ipv4(ifp, flags, &SIN(addr)->sin_addr, prefixlen,
                                   (struct in_addr *)dest_pnt, label);
        else if (af == AF_INET6)
-               connected_add_ipv6(ifp, flags, &SIN6(addr)->sin6_addr,
-                                  prefixlen, (struct in6_addr *)dest_pnt,
-                                  label);
+               connected_add_ipv6(ifp, flags, &SIN6(addr)->sin6_addr, NULL,
+                                  prefixlen, label);
 
        return 0;
 }
@@ -335,7 +323,7 @@ static void interface_info_ioctl(struct interface *ifp)
 void interface_list(struct zebra_ns *zns)
 {
        if (zns->ns_id != NS_DEFAULT) {
-               zlog_warn("interface_list: ignore NS %u", zns->ns_id);
+               zlog_debug("interface_list: ignore NS %u", zns->ns_id);
                return;
        }
        interface_list_ioctl(AF_INET);
@@ -359,3 +347,5 @@ struct connected *if_lookup_linklocal(struct interface *ifp)
 
        return NULL;
 }
+
+#endif /* SUNOS_5 */