]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/kernel_socket.c
zebra: dup addr detect clear cmd non-zero return
[mirror_frr.git] / zebra / kernel_socket.c
index b85c4748c4c138046b5f7fa9443f04689f273951..dcc22d2162ff67cc28afe2577f2ef1b486e40514 100644 (file)
@@ -39,6 +39,7 @@
 #include "rib.h"
 #include "privs.h"
 #include "vrf.h"
+#include "lib_errors.h"
 
 #include "zebra/rt.h"
 #include "zebra/interface.h"
@@ -46,6 +47,8 @@
 #include "zebra/debug.h"
 #include "zebra/kernel_socket.h"
 #include "zebra/rib.h"
+#include "zebra/zebra_errors.h"
+#include "zebra/zebra_ptm.h"
 
 extern struct zebra_privs_t zserv_privs;
 
@@ -275,6 +278,11 @@ static const struct message rtm_flag_str[] = {{RTF_UP, "UP"},
 /* Kernel routing update socket. */
 int routing_sock = -1;
 
+/* Kernel dataplane routing update socket, used in the dataplane pthread
+ * context.
+ */
+int dplane_routing_sock = -1;
+
 /* Yes I'm checking ugly routing socket behavior. */
 /* #define DEBUG */
 
@@ -324,7 +332,7 @@ static int ifan_read(struct if_announcemsghdr *ifan)
                                __func__, ifan->ifan_index, ifan->ifan_name);
 
                /* Create Interface */
-               ifp = if_get_by_name(ifan->ifan_name, VRF_DEFAULT, 0);
+               ifp = if_get_by_name(ifan->ifan_name, VRF_DEFAULT);
                if_set_index(ifp, ifan->ifan_index);
 
                if_get_metric(ifp);
@@ -407,7 +415,8 @@ int ifm_read(struct if_msghdr *ifm)
 
        /* paranoia: sanity check structure */
        if (ifm->ifm_msglen < sizeof(struct if_msghdr)) {
-               zlog_err("ifm_read: ifm->ifm_msglen %d too short\n",
+               flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR,
+                        "ifm_read: ifm->ifm_msglen %d too short\n",
                         ifm->ifm_msglen);
                return -1;
        }
@@ -466,7 +475,7 @@ int ifm_read(struct if_msghdr *ifm)
                if (ifnlen && (strncmp(ifp->name, ifname, IFNAMSIZ) != 0)) {
                        if (IS_ZEBRA_DEBUG_KERNEL)
                                zlog_debug(
-                                       "%s: ifp name %s doesnt match sdl name %s",
+                                       "%s: ifp name %s doesn't match sdl name %s",
                                        __func__, ifp->name, ifname);
                        ifp = NULL;
                }
@@ -499,8 +508,8 @@ int ifm_read(struct if_msghdr *ifm)
                 * RTA_IFP) is required.
                 */
                if (!ifnlen) {
-                       zlog_warn("Interface index %d (new) missing ifname\n",
-                                 ifm->ifm_index);
+                       zlog_debug("Interface index %d (new) missing ifname\n",
+                                  ifm->ifm_index);
                        return -1;
                }
 
@@ -583,7 +592,7 @@ int ifm_read(struct if_msghdr *ifm)
         */
        {
                if (ifp->ifindex != ifm->ifm_index) {
-                       zlog_warn(
+                       zlog_debug(
                                "%s: index mismatch, ifname %s, ifp index %d, "
                                "ifm index %d",
                                __func__, ifp->name, ifp->ifindex,
@@ -706,7 +715,7 @@ static void ifam_read_mesg(struct ifa_msghdr *ifm, union sockunion *addr,
 
        /* Assert read up end point matches to end point */
        if (pnt != end)
-               zlog_warn("ifam_read() doesn't read all socket data");
+               zlog_debug("ifam_read() doesn't read all socket data");
 }
 
 /* Interface's address information get. */
@@ -725,7 +734,8 @@ int ifam_read(struct ifa_msghdr *ifam)
        ifam_read_mesg(ifam, &addr, &mask, &brd, ifname, &ifnlen);
 
        if ((ifp = if_lookup_by_index(ifam->ifam_index, VRF_DEFAULT)) == NULL) {
-               zlog_warn("%s: no interface for ifname %s, index %d", __func__,
+               flog_warn(EC_ZEBRA_UNKNOWN_INTERFACE,
+                         "%s: no interface for ifname %s, index %d", __func__,
                          ifname, ifam->ifam_index);
                return -1;
        }
@@ -819,10 +829,10 @@ static int rtm_read_mesg(struct rt_msghdr *rtm, union sockunion *dest,
 
        /* rt_msghdr version check. */
        if (rtm->rtm_version != RTM_VERSION)
-               zlog_warn(
-                       "Routing message version different %d should be %d."
-                       "This may cause problem\n",
-                       rtm->rtm_version, RTM_VERSION);
+               flog_warn(EC_ZEBRA_RTM_VERSION_MISMATCH,
+                         "Routing message version different %d should be %d."
+                         "This may cause problem\n",
+                         rtm->rtm_version, RTM_VERSION);
 
        /* Be sure structure is cleared */
        memset(dest, 0, sizeof(union sockunion));
@@ -857,7 +867,7 @@ static int rtm_read_mesg(struct rt_msghdr *rtm, union sockunion *dest,
 
        /* Assert read up to the end of pointer. */
        if (pnt != end)
-               zlog_warn("rtm_read() doesn't read all socket data.");
+               zlog_debug("rtm_read() doesn't read all socket data.");
 
        return rtm->rtm_flags;
 }
@@ -1043,7 +1053,7 @@ void rtm_read(struct rt_msghdr *rtm)
                if (rtm->rtm_type == RTM_CHANGE)
                        rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
                                   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  NULL, 0, 0, true);
+                                  NULL, 0, 0, 0, true);
 
                if (!nh.type) {
                        nh.type = NEXTHOP_TYPE_IPV4;
@@ -1058,7 +1068,7 @@ void rtm_read(struct rt_msghdr *rtm)
                else
                        rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
                                   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  &nh, 0, 0, true);
+                                  &nh, 0, 0, 0, true);
        }
        if (dest.sa.sa_family == AF_INET6) {
                /* One day we might have a debug section here like one in the
@@ -1089,7 +1099,7 @@ void rtm_read(struct rt_msghdr *rtm)
                if (rtm->rtm_type == RTM_CHANGE)
                        rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
                                   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  NULL, 0, 0, true);
+                                  NULL, 0, 0, 0, true);
 
                if (!nh.type) {
                        nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
@@ -1106,7 +1116,7 @@ void rtm_read(struct rt_msghdr *rtm)
                else
                        rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
                                   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  &nh, 0, 0, true);
+                                  &nh, 0, 0, 0, true);
        }
 }
 
@@ -1131,7 +1141,7 @@ int rtm_write(int message, union sockunion *dest, union sockunion *mask,
                char buf[512];
        } msg;
 
-       if (routing_sock < 0)
+       if (dplane_routing_sock < 0)
                return ZEBRA_ERR_EPERM;
 
        /* Clear and set rt_msghdr values */
@@ -1179,7 +1189,8 @@ int rtm_write(int message, union sockunion *dest, union sockunion *mask,
                        if (mask)
                                inet_ntop(AF_INET, &mask->sin.sin_addr,
                                          mask_buf, INET_ADDRSTRLEN);
-                       zlog_warn(
+                       flog_warn(
+                               EC_ZEBRA_RTM_NO_GATEWAY,
                                "%s: %s/%s: gate == NULL and no gateway found for ifindex %d",
                                __func__, dest_buf, mask_buf, index);
                        return -1;
@@ -1237,7 +1248,7 @@ int rtm_write(int message, union sockunion *dest, union sockunion *mask,
 
        msg.rtm.rtm_msglen = pnt - (caddr_t)&msg;
 
-       ret = write(routing_sock, &msg, msg.rtm.rtm_msglen);
+       ret = write(dplane_routing_sock, &msg, msg.rtm.rtm_msglen);
 
        if (ret != msg.rtm.rtm_msglen) {
                if (errno == EEXIST)
@@ -1247,8 +1258,8 @@ int rtm_write(int message, union sockunion *dest, union sockunion *mask,
                if (errno == ESRCH)
                        return ZEBRA_ERR_RTNOEXIST;
 
-               zlog_warn("%s: write : %s (%d)", __func__, safe_strerror(errno),
-                         errno);
+               flog_err_sys(EC_LIB_SOCKET, "%s: write : %s (%d)", __func__,
+                            safe_strerror(errno), errno);
                return ZEBRA_ERR_KERNEL;
        }
        return ZEBRA_ERR_NOERROR;
@@ -1330,8 +1341,8 @@ static int kernel_read(struct thread *thread)
 
        if (nbytes <= 0) {
                if (nbytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
-                       zlog_warn("routing socket error: %s",
-                                 safe_strerror(errno));
+                       flog_err_sys(EC_LIB_SOCKET, "routing socket error: %s",
+                                    safe_strerror(errno));
                return 0;
        }
 
@@ -1347,7 +1358,7 @@ static int kernel_read(struct thread *thread)
         * can assume they have the whole message.
         */
        if (rtm->rtm_msglen != nbytes) {
-               zlog_warn(
+               zlog_debug(
                        "kernel_read: rtm->rtm_msglen %d, nbytes %d, type %d\n",
                        rtm->rtm_msglen, nbytes, rtm->rtm_type);
                return -1;
@@ -1382,16 +1393,21 @@ static int kernel_read(struct thread *thread)
 /* Make routing socket. */
 static void routing_socket(struct zebra_ns *zns)
 {
-       if (zserv_privs.change(ZPRIVS_RAISE))
-               zlog_err("routing_socket: Can't raise privileges");
+       frr_elevate_privs(&zserv_privs) {
+               routing_sock = ns_socket(AF_ROUTE, SOCK_RAW, 0, zns->ns_id);
 
-       routing_sock =
-               ns_socket(AF_ROUTE, SOCK_RAW, 0, zns->ns_id);
+               dplane_routing_sock =
+                       ns_socket(AF_ROUTE, SOCK_RAW, 0, zns->ns_id);
+       }
 
        if (routing_sock < 0) {
-               if (zserv_privs.change(ZPRIVS_LOWER))
-                       zlog_err("routing_socket: Can't lower privileges");
-               zlog_warn("Can't init kernel routing socket");
+               flog_err_sys(EC_LIB_SOCKET, "Can't init kernel routing socket");
+               return;
+       }
+
+       if (dplane_routing_sock < 0) {
+               flog_err_sys(EC_LIB_SOCKET,
+                            "Can't init kernel dataplane routing socket");
                return;
        }
 
@@ -1402,9 +1418,6 @@ static void routing_socket(struct zebra_ns *zns)
        /*if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0)
          zlog_warn ("Can't set O_NONBLOCK to routing socket");*/
 
-       if (zserv_privs.change(ZPRIVS_LOWER))
-               zlog_err("routing_socket: Can't lower privileges");
-
        /* kernel_read needs rewrite. */
        thread_add_read(zebrad.master, kernel_read, NULL, routing_sock, NULL);
 }
@@ -1416,7 +1429,7 @@ void kernel_init(struct zebra_ns *zns)
        routing_socket(zns);
 }
 
-void kernel_terminate(struct zebra_ns *zns)
+void kernel_terminate(struct zebra_ns *zns, bool complete)
 {
        return;
 }