> +the in-band support as the following. Perhaps change 'as the following' to 'with the following command'
-Reid On Thu, Jan 31, 2013 at 2:49 AM, YAMAMOTO Takashi <yamam...@valinux.co.jp> wrote: > From: YAMAMOTO Takashi <y...@mwd.biglobe.ne.jp> > > Signed-off-by: YAMAMOTO Takashi <yamam...@valinux.co.jp> > --- > INSTALL.userspace | 6 +-- > lib/netdev-bsd.c | 151 > +++++++++++++++++++++++++++++++++++++++++++++++++++++- > 2 files changed, 152 insertions(+), 5 deletions(-) > > diff --git a/INSTALL.userspace b/INSTALL.userspace > index 65ad499..5f9a9d8 100644 > --- a/INSTALL.userspace > +++ b/INSTALL.userspace > @@ -51,9 +51,9 @@ ovs-vswitchd will create a TAP device as the bridge's local > interface, > named the same as the bridge, as well as for each configured internal > interface. > > -Currently, on FreeBSD and NetBSD, the functionality required for in-band > -control support is not implemented. To avoid related errors, you can > -disable the in-band support as the following. > +Currently, on FreeBSD, the functionality required for in-band control > +support is not implemented. To avoid related errors, you can disable > +the in-band support as the following. > > ovs-vsctl set bridge br0 other_config:disable-in-band=true > > diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c > index 1cb1d8b..f35ca71 100644 > --- a/lib/netdev-bsd.c > +++ b/lib/netdev-bsd.c > @@ -1,5 +1,6 @@ > /* > * Copyright (c) 2011 Gaetano Catalli. > + * Copyright (c) 2013 YAMAMOTO Takashi. > * > * Licensed under the Apache License, Version 2.0 (the "License"); > * you may not use this file except in compliance with the License. > @@ -38,6 +39,9 @@ > #include <string.h> > #include <unistd.h> > #include <sys/sysctl.h> > +#if defined(__NetBSD__) > +#include <net/route.h> > +#endif > > #include "rtbsd.h" > #include "coverage.h" > @@ -1244,6 +1248,149 @@ netdev_bsd_get_in6(const struct netdev *netdev_, > struct in6_addr *in6) > return 0; > } > > +#if defined(__NetBSD__) > +static struct netdev_dev * > +find_netdev_by_kernel_name(const char *kernel_name) > +{ > + struct shash device_shash; > + struct shash_node *node; > + > + shash_init(&device_shash); > + netdev_dev_get_devices(&netdev_tap_class, &device_shash); > + SHASH_FOR_EACH(node, &device_shash) { > + struct netdev_dev_bsd * const dev = node->data; > + > + if (!strcmp(dev->kernel_name, kernel_name)) { > + shash_destroy(&device_shash); > + return &dev->netdev_dev; > + } > + } > + shash_destroy(&device_shash); > + return NULL; > +} > + > +static const char * > +netdev_bsd_convert_kernel_name_to_ovs_name(const char *kernel_name) > +{ > + const struct netdev_dev * const netdev_dev = > + find_netdev_by_kernel_name(kernel_name); > + > + if (netdev_dev == NULL) { > + return NULL; > + } > + return netdev_dev_get_name(netdev_dev); > +} > +#endif > + > +static int > +netdev_bsd_get_next_hop(const struct in_addr *host, struct in_addr *next_hop, > + char **netdev_name) > +{ > +#if defined(__NetBSD__) > + static int seq = 0; > + struct sockaddr_in sin; > + struct sockaddr_dl sdl; > + int s; > + int i; > + struct { > + struct rt_msghdr h; > + char space[512]; > + } buf; > + struct rt_msghdr *rtm = &buf.h; > + const pid_t pid = getpid(); > + char *cp; > + ssize_t ssz; > + bool gateway = false; > + char *ifname = NULL; > + int saved_errno; > + > + memset(next_hop, 0, sizeof(*next_hop)); > + *netdev_name = NULL; > + > + memset(&sin, 0, sizeof(sin)); > + sin.sin_len = sizeof(sin); > + sin.sin_family = AF_INET; > + sin.sin_port = 0; > + sin.sin_addr = *host; > + > + memset(&sdl, 0, sizeof(sdl)); > + sdl.sdl_len = sizeof(sdl); > + sdl.sdl_family = AF_LINK; > + > + s = socket(PF_ROUTE, SOCK_RAW, 0); > + memset(&buf, 0, sizeof(buf)); > + rtm->rtm_flags = RTF_HOST|RTF_UP; > + rtm->rtm_version = RTM_VERSION; > + rtm->rtm_addrs = RTA_DST|RTA_IFP; > + cp = (void *)&buf.space; > + memcpy(cp, &sin, sizeof(sin)); > + RT_ADVANCE(cp, (struct sockaddr *)(void *)&sin); > + memcpy(cp, &sdl, sizeof(sdl)); > + RT_ADVANCE(cp, (struct sockaddr *)(void *)&sdl); > + rtm->rtm_msglen = cp - (char *)(void *)rtm; > + rtm->rtm_seq = ++seq; > + rtm->rtm_type = RTM_GET; > + rtm->rtm_pid = pid; > + write(s, rtm, rtm->rtm_msglen); > + memset(&buf, 0, sizeof(buf)); > + do { > + ssz = read(s, &buf, sizeof(buf)); > + } while (ssz > 0 && (rtm->rtm_seq != seq || rtm->rtm_pid != pid)); > + saved_errno = errno; > + close(s); > + if (ssz <= 0) { > + if (ssz < 0) { > + return saved_errno; > + } > + return EPIPE; /* XXX */ > + } > + cp = (void *)&buf.space; > + for (i = 1; i; i <<= 1) { > + if ((rtm->rtm_addrs & i) != 0) { > + const struct sockaddr *sa = (const void *)cp; > + > + if ((i == RTA_GATEWAY) && sa->sa_family == AF_INET) { > + const struct sockaddr_in * const sin = > + (const struct sockaddr_in *)sa; > + > + *next_hop = sin->sin_addr; > + gateway = true; > + } > + if ((i == RTA_IFP) && sa->sa_family == AF_LINK) { > + const struct sockaddr_dl * const sdl = > + (const struct sockaddr_dl *)sa; > + const size_t nlen = sdl->sdl_nlen; > + char * const kernel_name = xmalloc(nlen + 1); > + const char *name; > + > + memcpy(kernel_name, sdl->sdl_data, nlen); > + kernel_name[nlen] = 0; > + name = > netdev_bsd_convert_kernel_name_to_ovs_name(kernel_name); > + if (name == NULL) { > + ifname = xstrdup(kernel_name); > + } else { > + ifname = xstrdup(name); > + } > + free(kernel_name); > + } > + RT_ADVANCE(cp, sa); > + } > + } > + if (ifname == NULL) { > + return ENXIO; > + } > + if (!gateway) { > + *next_hop = *host; > + } > + *netdev_name = ifname; > + VLOG_DBG("host " IP_FMT " next-hop " IP_FMT " if %s", > + IP_ARGS(host->s_addr), IP_ARGS(next_hop->s_addr), *netdev_name); > + return 0; > +#else > + return ENOTSUP; > +#endif > +} > + > static void > make_in4_sockaddr(struct sockaddr *sa, struct in_addr addr) > { > @@ -1373,7 +1520,7 @@ const struct netdev_class netdev_bsd_class = { > netdev_bsd_set_in4, > netdev_bsd_get_in6, > NULL, /* add_router */ > - NULL, /* get_next_hop */ > + netdev_bsd_get_next_hop, > NULL, /* get_status */ > NULL, /* arp_lookup */ > > @@ -1434,7 +1581,7 @@ const struct netdev_class netdev_tap_class = { > netdev_bsd_set_in4, > netdev_bsd_get_in6, > NULL, /* add_router */ > - NULL, /* get_next_hop */ > + netdev_bsd_get_next_hop, > NULL, /* get_status */ > NULL, /* arp_lookup */ > > -- > 1.7.12 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev