]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/libsystemd/sd-netlink/sd-netlink.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / libsystemd / sd-netlink / sd-netlink.c
index 91701405a59ee0628461900cbfc87e82d2d18193..924b0c954fdfdc3c81b2810db157ba45b348e130 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -44,7 +45,7 @@ static int sd_netlink_new(sd_netlink **ret) {
         rtnl->n_ref = REFCNT_INIT;
         rtnl->fd = -1;
         rtnl->sockaddr.nl.nl_family = AF_NETLINK;
-        rtnl->original_pid = getpid();
+        rtnl->original_pid = getpid_cached();
 
         LIST_HEAD_INIT(rtnl->match_callbacks);
 
@@ -99,7 +100,7 @@ static bool rtnl_pid_changed(sd_netlink *rtnl) {
         /* We don't support people creating an rtnl connection and
          * keeping it around over a fork(). Let's complain. */
 
-        return rtnl->original_pid != getpid();
+        return rtnl->original_pid != getpid_cached();
 }
 
 int sd_netlink_open_fd(sd_netlink **ret, int fd) {
@@ -144,7 +145,10 @@ int sd_netlink_open(sd_netlink **ret) {
         return 0;
 }
 
-int sd_netlink_inc_rcvbuf(const sd_netlink *const rtnl, const int size) {
+int sd_netlink_inc_rcvbuf(sd_netlink *rtnl, size_t size) {
+        assert_return(rtnl, -EINVAL);
+        assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
+
         return fd_inc_rcvbuf(rtnl->fd, size);
 }
 
@@ -273,6 +277,10 @@ static int dispatch_rqueue(sd_netlink *rtnl, sd_netlink_message **message) {
         if (rtnl->rqueue_size <= 0) {
                 /* Try to read a new message */
                 r = socket_read_message(rtnl);
+                if (r == -ENOBUFS) { /* FIXME: ignore buffer overruns for now */
+                        log_debug_errno(r, "Got ENOBUFS from netlink socket, ignoring.");
+                        return 1;
+                }
                 if (r <= 0)
                         return r;
         }
@@ -887,6 +895,16 @@ int sd_netlink_add_match(sd_netlink *rtnl,
                         if (r < 0)
                                 return r;
                         break;
+                case RTM_NEWRULE:
+                case RTM_DELRULE:
+                        r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV4_RULE);
+                        if (r < 0)
+                                return r;
+
+                        r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV6_RULE);
+                        if (r < 0)
+                                return r;
+                        break;
                 default:
                         return -EOPNOTSUPP;
         }