]> granicus.if.org Git - libnl/commitdiff
link: generic link enslaving API
authorThomas Graf <tgraf@redhat.com>
Mon, 7 Nov 2011 11:32:35 +0000 (12:32 +0100)
committerThomas Graf <tgraf@redhat.com>
Mon, 7 Nov 2011 11:32:35 +0000 (12:32 +0100)
Adds rtnl_link_enslave() / rtnl_link_release() providing a genreic
link enslaving/release API for use with all link types which use
the IFLA_MASTER property.

include/netlink/route/link.h
lib/route/link.c

index 79c2d5640f228912964774a41a53b1b72b49ecfd..42ef7c832df52adb650d06bd4520354e3d548c38 100644 (file)
@@ -197,6 +197,12 @@ extern int rtnl_link_set_stat(struct rtnl_link *, rtnl_link_stat_id_t,
 extern int     rtnl_link_set_type(struct rtnl_link *, const char *);
 extern char *  rtnl_link_get_type(struct rtnl_link *);
 
+extern int     rtnl_link_enslave_ifindex(struct nl_sock *, int, int);
+extern int     rtnl_link_enslave(struct nl_sock *, struct rtnl_link *,
+                                 struct rtnl_link *);
+extern int     rtnl_link_release_ifindex(struct nl_sock *, int);
+extern int     rtnl_link_release(struct nl_sock *, struct rtnl_link *);
+
 /* deprecated */
 extern int     rtnl_link_set_info_type(struct rtnl_link *, const char *) __attribute__((deprecated));
 extern char *  rtnl_link_get_info_type(struct rtnl_link *) __attribute__((deprecated));
index b252f39baa3d3063febcacd72bac044a97f85a13..6d9b8e913751bdcff6a5631651a8b2ada8282ef5 100644 (file)
@@ -1979,6 +1979,129 @@ char *rtnl_link_get_type(struct rtnl_link *link)
 
 /** @} */
 
+/**
+ * @name Master/Slave
+ * @{
+ */
+
+/**
+ * Enslave slave link to master link
+ * @arg sock           netlink socket
+ * @arg master         ifindex of master link
+ * @arg slave          ifindex of slave link
+ *
+ * This function is identical to rtnl_link_enslave() except that
+ * it takes interface indices instead of rtnl_link objects.
+ *
+ * @see rtnl_link_enslave()
+ *
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_link_enslave_ifindex(struct nl_sock *sock, int master, int slave)
+{
+       struct rtnl_link *link;
+       int err;
+
+       if (!(link = rtnl_link_alloc()))
+               return -NLE_NOMEM;
+
+       rtnl_link_set_ifindex(link, slave);
+       rtnl_link_set_master(link, master);
+       
+       if ((err = rtnl_link_change(sock, link, link, 0)) < 0)
+               goto errout;
+
+       rtnl_link_put(link);
+
+       /*
+        * Due to the kernel not signaling whether this opertion is
+        * supported or not, we will retrieve the attribute to see  if the
+        * request was successful. If the master assigned remains unchanged
+        * we will return NLE_OPNOTSUPP to allow performing backwards
+        * compatibility of some sort.
+        */
+       if ((err = rtnl_link_get_kernel(sock, slave, NULL, &link)) < 0)
+               return err;
+
+       if (rtnl_link_get_master(link) != master)
+               err = -NLE_OPNOTSUPP;
+
+errout:
+       rtnl_link_put(link);
+
+       return err;
+}
+
+/**
+ * Enslave slave link to master link
+ * @arg sock           netlink socket
+ * @arg master         master link
+ * @arg slave          slave link
+ *
+ * Constructs a RTM_NEWLINK or RTM_SETLINK message adding the slave to
+ * the master and sends the request via the specified netlink socket.
+ *
+ * @note The feature of enslaving/releasing via netlink has only been added
+ *       recently to the kernel (Feb 2011). Also, the kernel does not signal
+ *       if the operation is not supported. Therefore this function will
+ *       verify if the master assignment has changed and will return
+ *       -NLE_OPNOTSUPP if it did not.
+ *
+ * @see rtnl_link_enslave_ifindex()
+ * @see rtnl_link_release()
+ *
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_link_enslave(struct nl_sock *sock, struct rtnl_link *master,
+                     struct rtnl_link *slave)
+{
+       return rtnl_link_enslave_ifindex(sock, rtnl_link_get_ifindex(master),
+                                        rtnl_link_get_ifindex(slave));
+}
+
+/**
+ * Release slave link from its master
+ * @arg sock           netlink socket
+ * @arg slave          slave link
+ *
+ * This function is identical to rtnl_link_release() except that
+ * it takes an interface index instead of a rtnl_link object.
+ *
+ * @see rtnl_link_release()
+ *
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_link_release_ifindex(struct nl_sock *sock, int slave)
+{
+       return rtnl_link_enslave_ifindex(sock, 0, slave);
+}
+
+/**
+ * Release slave link from its master
+ * @arg sock           netlink socket
+ * @arg slave          slave link
+ *
+ * Constructs a RTM_NEWLINK or RTM_SETLINK message releasing the slave from
+ * its master and sends the request via the specified netlink socket.
+ *
+ * @note The feature of enslaving/releasing via netlink has only been added
+ *       recently to the kernel (Feb 2011). Also, the kernel does not signal
+ *       if the operation is not supported. Therefore this function will
+ *       verify if the master assignment has changed and will return
+ *       -NLE_OPNOTSUPP if it did not.
+ *
+ * @see rtnl_link_release_ifindex()
+ * @see rtnl_link_enslave()
+ *
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_link_release(struct nl_sock *sock, struct rtnl_link *slave)
+{
+       return rtnl_link_release_ifindex(sock, rtnl_link_get_ifindex(slave));
+}
+
+/** @} */
+
 /**
  * @name Utilities
  * @{