pespin submitted this change.
netdev: Add API osmo_netdev_del_addr()
Change-Id: I75153eb59e96a6a2505dc5b29432c76e5c21ea24
---
M TODO-RELEASE
M include/osmocom/core/netdev.h
M src/core/libosmocore.map
M src/core/netdev.c
4 files changed, 80 insertions(+), 0 deletions(-)
diff --git a/TODO-RELEASE b/TODO-RELEASE
index 0ed7189..ee01c5b 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -7,3 +7,4 @@
# If any interfaces have been added since the last public release: c:r:a + 1.
# If any interfaces have been removed or changed since the last public release: c:r:0.
#library what description / commit summary line
+core add osmo_netdev_del_addr()
diff --git a/include/osmocom/core/netdev.h b/include/osmocom/core/netdev.h
index 4d505fe..33dc4ec 100644
--- a/include/osmocom/core/netdev.h
+++ b/include/osmocom/core/netdev.h
@@ -42,6 +42,8 @@
void osmo_netdev_set_mtu_chg_cb(struct osmo_netdev *netdev, osmo_netdev_mtu_chg_cb_t mtu_chg_cb);
int osmo_netdev_add_addr(struct osmo_netdev *netdev, const struct osmo_sockaddr *addr, uint8_t prefixlen);
+int osmo_netdev_del_addr(struct osmo_netdev *netdev, const struct osmo_sockaddr *addr, uint8_t prefixlen);
+
int osmo_netdev_add_route(struct osmo_netdev *netdev, const struct osmo_sockaddr *dst_addr,
uint8_t dst_prefixlen, const struct osmo_sockaddr *gw_addr);
int osmo_netdev_ifupdown(struct osmo_netdev *netdev, bool ifupdown);
diff --git a/src/core/libosmocore.map b/src/core/libosmocore.map
index 06a9009..0cb696b 100644
--- a/src/core/libosmocore.map
+++ b/src/core/libosmocore.map
@@ -323,6 +323,7 @@
osmo_netdev_add_addr;
osmo_netdev_add_route;
osmo_netdev_alloc;
+osmo_netdev_del_addr;
osmo_netdev_free;
osmo_netdev_get_dev_name;
osmo_netdev_get_ifindex;
diff --git a/src/core/netdev.c b/src/core/netdev.c
index be7ad2e..d9bc797 100644
--- a/src/core/netdev.c
+++ b/src/core/netdev.c
@@ -606,6 +606,50 @@
return 0;
}
+static int netdev_mnl_del_addr(struct osmo_mnl *omnl, unsigned int if_index, const struct osmo_sockaddr *osa, uint8_t prefix)
+{
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
+ struct ifaddrmsg *ifm;
+
+ nlh->nlmsg_type = RTM_DELADDR;
+ nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE | NLM_F_ACK;
+ nlh->nlmsg_seq = (uint32_t)time(NULL);
+
+ ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
+ ifm->ifa_family = osa->u.sa.sa_family;
+ ifm->ifa_prefixlen = prefix;
+ ifm->ifa_flags = IFA_F_PERMANENT;
+ ifm->ifa_scope = RT_SCOPE_UNIVERSE;
+ ifm->ifa_index = if_index;
+
+ /*
+ * The exact meaning of IFA_LOCAL and IFA_ADDRESS depend
+ * on the address family being used and the device type.
+ * For broadcast devices (like the interfaces we use),
+ * for IPv4 we specify both and they are used interchangeably.
+ * For IPv6, only IFA_ADDRESS needs to be set.
+ */
+ switch (osa->u.sa.sa_family) {
+ case AF_INET:
+ mnl_attr_put_u32(nlh, IFA_LOCAL, osa->u.sin.sin_addr.s_addr);
+ mnl_attr_put_u32(nlh, IFA_ADDRESS, osa->u.sin.sin_addr.s_addr);
+ break;
+ case AF_INET6:
+ mnl_attr_put(nlh, IFA_ADDRESS, sizeof(struct in6_addr), &osa->u.sin6.sin6_addr);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (mnl_socket_sendto(omnl->mnls, nlh, nlh->nlmsg_len) < 0) {
+ LOGP(DLGLOBAL, LOGL_ERROR, "mnl_socket_sendto\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
static int netdev_mnl_add_route(struct osmo_mnl *omnl,
unsigned int if_index,
const struct osmo_sockaddr *dst_osa,
@@ -983,6 +1027,38 @@
return rc;
}
+/*! Remove IP address from netdev interface
+ * \param[in] netdev The netdev object managing the netdev interface
+ * \param[in] addr The local address to remove from the interface
+ * \param[in] prefixlen The network prefix of addr
+ * \returns 0 on succes; negative on error.
+ */
+int osmo_netdev_del_addr(struct osmo_netdev *netdev, const struct osmo_sockaddr *addr, uint8_t prefixlen)
+{
+ struct osmo_netns_switch_state switch_state;
+ char buf[INET6_ADDRSTRLEN];
+ int rc;
+
+ if (!netdev->registered)
+ return -ENODEV;
+
+ LOGNETDEV(netdev, LOGL_NOTICE, "Deleting address %s/%u from dev %s\n",
+ osmo_sockaddr_ntop(&addr->u.sa, buf), prefixlen, netdev->dev_name);
+
+ NETDEV_NETNS_ENTER(netdev, &switch_state, "Delete address");
+
+#if ENABLE_LIBMNL
+ rc = netdev_mnl_del_addr(netdev->netns_ctx->omnl, netdev->ifindex, addr, prefixlen);
+#else
+ LOGNETDEV(netdev, LOGL_ERROR, "%s: NOT SUPPORTED. Build libosmocore with --enable-libmnl.\n", __func__);
+ rc = -ENOTSUP;
+#endif
+
+ NETDEV_NETNS_EXIT(netdev, &switch_state, "Delete address");
+
+ return rc;
+}
+
/*! Add IP route to netdev interface
* \param[in] netdev The netdev object managing the netdev interface
* \param[in] dst_addr The destination address of the route
To view, visit change 42443. To unsubscribe, or for help writing mail filters, visit settings.