2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-29 13:27:59 +00:00

netdev-linux: Create rtnetlink socket up front instead of on demand.

This simplifies a bit of existing code since it is known that an rtnetlink
socket will always be available.  It will simplify additional code in
upcoming commits.
This commit is contained in:
Ben Pfaff 2010-05-28 16:34:55 -07:00
parent 38a997566d
commit ff4ed3c9a1

View File

@ -125,6 +125,9 @@ struct netdev_linux {
/* An AF_INET socket (used for ioctl operations). */
static int af_inet_sock = -1;
/* A Netlink routing socket that is not subscribed to any multicast groups. */
static struct nl_sock *rtnl_sock;
struct netdev_linux_notifier {
struct netdev_notifier notifier;
struct list node;
@ -158,7 +161,6 @@ static int set_etheraddr(const char *netdev_name, int hwaddr_family,
const uint8_t[ETH_ADDR_LEN]);
static int get_stats_via_netlink(int ifindex, struct netdev_stats *stats);
static int get_stats_via_proc(const char *netdev_name, struct netdev_stats *stats);
static int get_rtnl_sock(struct nl_sock **);
static bool
is_netdev_linux_class(const struct netdev_class *netdev_class)
@ -184,17 +186,27 @@ netdev_linux_cast(const struct netdev *netdev)
return CONTAINER_OF(netdev, struct netdev_linux, netdev);
}
static int
netdev_linux_init(void)
{
static int status = -1;
if (status < 0) {
/* Create AF_INET socket. */
af_inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
status = af_inet_sock >= 0 ? 0 : errno;
if (status) {
VLOG_ERR("failed to create inet socket: %s", strerror(status));
}
/* Create rtnetlink socket. */
if (!status) {
status = nl_sock_create(NETLINK_ROUTE, 0, 0, 0, &rtnl_sock);
if (status) {
VLOG_ERR_RL(&rl, "failed to create rtnetlink socket: %s",
strerror(status));
}
}
}
return status;
}
@ -1117,7 +1129,6 @@ netdev_linux_remove_policing(struct netdev *netdev)
struct ofpbuf request;
struct ofpbuf *reply;
struct tcmsg *tcmsg;
struct nl_sock *rtnl_sock;
int ifindex;
int error;
@ -1126,11 +1137,6 @@ netdev_linux_remove_policing(struct netdev *netdev)
return error;
}
error = get_rtnl_sock(&rtnl_sock);
if (error) {
return error;
}
ofpbuf_init(&request, 0);
nl_msg_put_nlmsghdr(&request, sizeof *tcmsg, RTM_DELQDISC, NLM_F_REQUEST);
tcmsg = ofpbuf_put_zeros(&request, sizeof *tcmsg);
@ -1679,7 +1685,6 @@ get_stats_via_netlink(int ifindex, struct netdev_stats *stats)
.min_len = sizeof(struct rtnl_link_stats) },
};
struct nl_sock *rtnl_sock;
struct ofpbuf request;
struct ofpbuf *reply;
struct ifinfomsg *ifi;
@ -1687,11 +1692,6 @@ get_stats_via_netlink(int ifindex, struct netdev_stats *stats)
struct nlattr *attrs[ARRAY_SIZE(rtnlgrp_link_policy)];
int error;
error = get_rtnl_sock(&rtnl_sock);
if (error) {
return error;
}
ofpbuf_init(&request, 0);
nl_msg_put_nlmsghdr(&request, sizeof *ifi, RTM_GETLINK, NLM_F_REQUEST);
ifi = ofpbuf_put_zeros(&request, sizeof *ifi);
@ -1952,26 +1952,3 @@ netdev_linux_get_ipv4(const struct netdev *netdev, struct in_addr *ip,
}
return error;
}
/* Obtains a Netlink routing socket that is not subscribed to any multicast
* groups. Returns 0 if successful, otherwise a positive errno value. Stores
* the socket in '*rtnl_sockp' if successful, otherwise a null pointer. */
static int
get_rtnl_sock(struct nl_sock **rtnl_sockp)
{
static struct nl_sock *sock;
int error;
if (!sock) {
error = nl_sock_create(NETLINK_ROUTE, 0, 0, 0, &sock);
if (error) {
VLOG_ERR_RL(&rl, "failed to create rtnetlink socket: %s",
strerror(error));
}
} else {
error = 0;
}
*rtnl_sockp = sock;
return error;
}