int speed;
int mtu;
uint32_t features;
+ struct in_addr in4;
+ struct in6_addr in6;
int save_flags;
};
static void init_netdev(void);
static int restore_flags(struct netdev *netdev);
-/* Check whether device NAME has an IPv4 address assigned to it and, if so, log
- * an error. */
-static void
-check_ipv4_address(const char *name)
+/* Obtains the IPv4 address for 'name' into 'in4'. Returns true if
+ * successful. */
+static bool
+get_ipv4_address(const char *name, struct in_addr *in4)
{
int sock;
struct ifreq ifr;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
VLOG_WARN("socket(AF_INET): %s", strerror(errno));
- return;
+ return false;
}
strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
ifr.ifr_addr.sa_family = AF_INET;
if (ioctl(sock, SIOCGIFADDR, &ifr) == 0) {
- VLOG_ERR("%s device has assigned IP address %s", name,
- inet_ntoa(((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr));
+ struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.ifr_addr;
+ *in4 = sin->sin_addr;
+ } else {
+ in4->s_addr = INADDR_ANY;
}
close(sock);
+ return true;
}
-/* Check whether device NAME has an IPv6 address assigned to it and, if so, log
- * an error. */
+/* Obtains the IPv6 address for 'name' into 'in6'. */
static void
-check_ipv6_address(const char *name)
+get_ipv6_address(const char *name, struct in6_addr *in6)
{
FILE *file;
char line[128];
file = fopen("/proc/net/if_inet6", "r");
if (file == NULL) {
+ /* This most likely indicates that the host doesn't have IPv6 support,
+ * so it's not really a failure condition.*/
+ *in6 = in6addr_any;
return;
}
while (fgets(line, sizeof line, file)) {
- struct in6_addr in6;
- uint8_t *s6 = in6.s6_addr;
+ uint8_t *s6 = in6->s6_addr;
char ifname[16 + 1];
#define X8 "%2"SCNx8
ifname) == 17
&& !strcmp(name, ifname))
{
- char in6_name[INET6_ADDRSTRLEN + 1];
- inet_ntop(AF_INET6, &in6, in6_name, sizeof in6_name);
- VLOG_ERR("%s device has assigned IPv6 address %s",
- name, in6_name);
+ return;
}
}
+ *in6 = in6addr_any;
fclose(file);
}
socklen_t rcvbuf_len;
size_t rcvbuf;
uint8_t etheraddr[ETH_ADDR_LEN];
+ struct in_addr in4;
+ struct in6_addr in6;
int mtu;
int error;
struct netdev *netdev;
}
mtu = ifr.ifr_mtu;
+ if (!get_ipv4_address(name, &in4)) {
+ goto error;
+ }
+ get_ipv6_address(name, &in6);
+
/* Allocate network device. */
netdev = xmalloc(sizeof *netdev);
netdev->name = xstrdup(name);
netdev->fd = fd;
memcpy(netdev->etheraddr, etheraddr, sizeof etheraddr);
netdev->mtu = mtu;
+ netdev->in4 = in4;
+ netdev->in6 = in6;
/* Get speed, features. */
do_ethtool(netdev);
return error;
}
- /* Complain to administrator if any IP addresses are assigned to the
- * interface. We warn about this because packets received for that IP
- * address will be processed both by the kernel TCP/IP stack and by us as a
- * switch, which produces poor results. */
- check_ipv4_address(name);
- check_ipv6_address(name);
-
/* Success! */
*netdev_ = netdev;
return 0;
{
return netdev->features;
}
+
+/* If 'netdev' has an assigned IPv4 address, sets '*in4' to that address and
+ * returns true. Otherwise, returns false. */
+bool
+netdev_get_in4(const struct netdev *netdev, struct in_addr *in4)
+{
+ *in4 = netdev->in4;
+ return in4->s_addr != INADDR_ANY;
+}
+
+/* If 'netdev' has an assigned IPv6 address, sets '*in6' to that address and
+ * returns true. Otherwise, returns false. */
+bool
+netdev_get_in6(const struct netdev *netdev, struct in6_addr *in6)
+{
+ *in6 = netdev->in6;
+ return memcmp(in6, &in6addr_any, sizeof *in6) != 0;
+}
\f
static void restore_all_flags(void *aux);
dp_add_port(struct datapath *dp, const char *name)
{
struct netdev *netdev;
+ struct in6_addr in6;
+ struct in_addr in4;
struct sw_port *p;
int error;
if (error) {
return error;
}
+ if (netdev_get_in4(netdev, &in4)) {
+ VLOG_ERR("%s device has assigned IP address %s", name, inet_ntoa(in4));
+ }
+ if (netdev_get_in6(netdev, &in6)) {
+ char in6_name[INET6_ADDRSTRLEN + 1];
+ inet_ntop(AF_INET6, &in6, in6_name, sizeof in6_name);
+ VLOG_ERR("%s device has assigned IPv6 address %s", name, in6_name);
+ }
for (p = dp->ports; ; p++) {
if (p >= &dp->ports[ARRAY_SIZE(dp->ports)]) {
void
dp_update_port_flags(struct datapath *dp, const struct ofp_phy_port *opp)
{
- struct sw_port *p;
-
- p = &dp->ports[htons(opp->port_no)];
+ int port_no = ntohs(opp->port_no);
+ if (port_no < OFPP_MAX) {
+ struct sw_port *p = &dp->ports[port_no];
- /* Make sure the port id hasn't changed since this was sent */
- if (!p || memcmp(opp->hw_addr, netdev_get_etheraddr(p->netdev),
- ETH_ADDR_LEN) != 0)
- return;
-
- p->flags = htonl(opp->flags);
+ /* Make sure the port id hasn't changed since this was sent */
+ if (!p || memcmp(opp->hw_addr, netdev_get_etheraddr(p->netdev),
+ ETH_ADDR_LEN) != 0) {
+ return;
+ }
+ p->flags = htonl(opp->flags);
+ }
}
static void