X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fnetdev-linux.c;h=cd104b320c8650c255a58990ef3386c2427795f7;hb=d84d4b88d26e3f37ce24f1d3eebe0d70ef264f73;hp=384fdafee96818cb74e703ca7c5495fa705cb8f7;hpb=d39808227b8a8e794a7cb0b990f4fcb0f5daadf5;p=openvswitch diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 384fdafe..cd104b32 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -373,7 +373,6 @@ struct netdev_linux { /* Sockets used for ioctl operations. */ static int af_inet_sock = -1; /* AF_INET, SOCK_DGRAM. */ -static int af_packet_sock = -1; /* AF_PACKET, SOCK_RAW. */ /* A Netlink routing socket that is not subscribed to any multicast groups. */ static struct nl_sock *rtnl_sock; @@ -411,6 +410,7 @@ 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 af_packet_sock(void); static bool is_netdev_linux_class(const struct netdev_class *netdev_class) @@ -447,15 +447,6 @@ netdev_linux_init(void) status = af_inet_sock >= 0 ? 0 : errno; if (status) { VLOG_ERR("failed to create inet socket: %s", strerror(status)); - } else { - /* Create AF_PACKET socket. */ - af_packet_sock = socket(AF_PACKET, SOCK_RAW, 0); - status = af_packet_sock >= 0 ? 0 : errno; - if (status) { - VLOG_ERR("failed to create packet socket: %s", - strerror(status)); - } - set_nonblocking(af_packet_sock); } /* Create rtnetlink socket. */ @@ -843,6 +834,12 @@ netdev_linux_send(struct netdev *netdev_, const void *data, size_t size) struct iovec iov; int ifindex; int error; + int sock; + + sock = af_packet_sock(); + if (sock < 0) { + return sock; + } error = get_ifindex(netdev_, &ifindex); if (error) { @@ -866,7 +863,7 @@ netdev_linux_send(struct netdev *netdev_, const void *data, size_t size) msg.msg_controllen = 0; msg.msg_flags = 0; - retval = sendmsg(af_packet_sock, &msg, 0); + retval = sendmsg(sock, &msg, 0); } else { /* Use the netdev's own fd to send to this device. This is * essential for tap devices, because packets sent to a tap device @@ -2017,7 +2014,7 @@ netdev_linux_get_next_hop(const struct in_addr *host, struct in_addr *next_hop, while (fgets(line, sizeof line, stream)) { if (++ln >= 2) { char iface[17]; - uint32_t dest, gateway, mask; + ovs_be32 dest, gateway, mask; int refcnt, metric, mtu; unsigned int flags, use, window, irtt; @@ -2084,7 +2081,7 @@ netdev_linux_get_status(const struct netdev *netdev, struct shash *sh) * ENXIO indicates that there is not ARP table entry for 'ip' on 'netdev'. */ static int netdev_linux_arp_lookup(const struct netdev *netdev, - uint32_t ip, uint8_t mac[ETH_ADDR_LEN]) + ovs_be32 ip, uint8_t mac[ETH_ADDR_LEN]) { struct arpreq r; struct sockaddr_in sin; @@ -4238,3 +4235,22 @@ netdev_linux_get_ipv4(const struct netdev *netdev, struct in_addr *ip, } return error; } + +/* Returns an AF_PACKET raw socket or a negative errno value. */ +static int +af_packet_sock(void) +{ + static int sock = INT_MIN; + + if (sock == INT_MIN) { + sock = socket(AF_PACKET, SOCK_RAW, 0); + if (sock >= 0) { + set_nonblocking(sock); + } else { + sock = -errno; + VLOG_ERR("failed to create packet socket: %s", strerror(errno)); + } + } + + return sock; +}