chiark / gitweb /
tree-wide: spelling fixes
[elogind.git] / src / libsystemd / sd-rtnl / rtnl-message.c
index 165e84d7a0a1d2cdb11e31f305eed6ba86ab2c5f..a089fae044d02ca75fbeec0a8d47b9bb910e300c 100644 (file)
@@ -43,7 +43,7 @@ static int message_new_empty(sd_rtnl *rtnl, sd_rtnl_message **ret) {
 
         assert_return(ret, -EINVAL);
 
-        /* Note that 'rtnl' is curretly unused, if we start using it internally
+        /* Note that 'rtnl' is currently unused, if we start using it internally
            we must take care to avoid problems due to mutual references between
            busses and their queued messages. See sd-bus.
          */
@@ -220,6 +220,58 @@ int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
         return 0;
 }
 
+int sd_rtnl_message_neigh_set_flags(sd_rtnl_message *m, uint8_t flags) {
+        struct ndmsg *ndm;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
+
+        ndm = NLMSG_DATA(m->hdr);
+        ndm->ndm_flags |= flags;
+
+        return 0;
+}
+
+int sd_rtnl_message_neigh_set_state(sd_rtnl_message *m, uint16_t state) {
+        struct ndmsg *ndm;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
+
+        ndm = NLMSG_DATA(m->hdr);
+        ndm->ndm_state |= state;
+
+        return 0;
+}
+
+int sd_rtnl_message_neigh_get_flags(sd_rtnl_message *m, uint8_t *flags) {
+        struct ndmsg *ndm;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
+
+        ndm = NLMSG_DATA(m->hdr);
+        *flags = ndm->ndm_flags;
+
+        return 0;
+}
+
+int sd_rtnl_message_neigh_get_state(sd_rtnl_message *m, uint16_t *state) {
+        struct ndmsg *ndm;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
+
+        ndm = NLMSG_DATA(m->hdr);
+        *state = ndm->ndm_state;
+
+        return 0;
+}
+
 int sd_rtnl_message_neigh_get_family(sd_rtnl_message *m, int *family) {
         struct ndmsg *ndm;
 
@@ -255,7 +307,9 @@ int sd_rtnl_message_new_neigh(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t nlm
         int r;
 
         assert_return(rtnl_message_type_is_neigh(nlmsg_type), -EINVAL);
-        assert_return(ndm_family == AF_INET || ndm_family == AF_INET6, -EINVAL);
+        assert_return(ndm_family == AF_INET  ||
+                      ndm_family == AF_INET6 ||
+                      ndm_family == PF_BRIDGE, -EINVAL);
         assert_return(ret, -EINVAL);
 
         r = message_new(rtnl, ret, nlmsg_type);
@@ -1294,8 +1348,10 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
                 /* no data */
                 if (errno == ENOBUFS)
                         log_debug("rtnl: kernel receive buffer overrun");
+                else if (errno == EAGAIN)
+                        log_debug("rtnl: no data in socket");
 
-                return (errno == EAGAIN) ? 0 : -errno;
+                return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
         } else if (r == 0)
                 /* connection was closed by the kernel */
                 return -ECONNRESET;
@@ -1307,8 +1363,10 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
                         struct ucred *ucred = (void *)CMSG_DATA(cmsg);
 
                         /* from the kernel */
-                        if (ucred->uid == 0 && ucred->pid == 0)
+                        if (ucred->pid == 0)
                                 auth = true;
+                        else
+                                log_debug("rtnl: ignoring message from pid %u", ucred->pid);
                 } else if (cmsg->cmsg_level == SOL_NETLINK &&
                            cmsg->cmsg_type == NETLINK_PKTINFO &&
                            cmsg->cmsg_len == CMSG_LEN(sizeof(struct nl_pktinfo))) {
@@ -1319,9 +1377,17 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
                 }
         }
 
-        if (!auth)
+        if (!auth) {
                 /* not from the kernel, ignore */
+                if (peek) {
+                        /* drop the message */
+                        r = recvmsg(fd, &msg, 0);
+                        if (r < 0)
+                                return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
+                }
+
                 return 0;
+        }
 
         if (group)
                 *_group = group;