-static int
-if_up(const char *name)
-{
- struct ifreq ifr;
-
- strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
- ifr.ifr_flags = IFF_UP;
-
- if (ioctl(af_inet_sock, SIOCSIFFLAGS, &ifr) == -1) {
- VLOG_DBG_RL(&rl, "%s: failed to bring device up: %s",
- name, strerror(errno));
- return errno;
- }
-
- return 0;
-}
-
-/* A veth may be created using the 'command' "+<name>,<peer>". A veth may
- * be destroyed by using the 'command' "-<name>", where <name> can be
- * either side of the device.
- */
-static int
-modify_veth(const char *format, ...)
-{
- FILE *veth_file;
- va_list args;
- int retval;
-
- veth_file = fopen("/sys/class/net/veth_pairs", "w");
- if (!veth_file) {
- VLOG_WARN_RL(&rl, "could not open veth device. Are you running a "
- "supported XenServer with the kernel module loaded?");
- return ENODEV;
- }
- setvbuf(veth_file, NULL, _IONBF, 0);
-
- va_start(args, format);
- retval = vfprintf(veth_file, format, args);
- va_end(args);
-
- fclose(veth_file);
- if (retval < 0) {
- VLOG_WARN_RL(&rl, "could not destroy patch: %s", strerror(errno));
- return errno;
- }
-
- return 0;
-}
-
-static int
-create_patch(const char *name, const char *peer)
-{
- int retval;
- struct netdev_dev *peer_nd;
-
-
- /* Only create the veth if the peer didn't already do it. */
- peer_nd = netdev_dev_from_name(peer);
- if (peer_nd) {
- if (!strcmp("patch", netdev_dev_get_type(peer_nd))) {
- struct netdev_dev_linux *ndl = netdev_dev_linux_cast(peer_nd);
- if (!strcmp(name, ndl->state.patch.peer)) {
- return 0;
- } else {
- VLOG_WARN_RL(&rl, "peer '%s' already paired with '%s'",
- peer, ndl->state.patch.peer);
- return EINVAL;
- }
- } else {
- VLOG_WARN_RL(&rl, "peer '%s' exists and is not a patch", peer);
- return EINVAL;
- }
- }
-
- retval = modify_veth("+%s,%s", name, peer);
- if (retval) {
- return retval;
- }
-
- retval = if_up(name);
- if (retval) {
- return retval;
- }
-
- retval = if_up(peer);
- if (retval) {
- return retval;
- }
-
- return 0;
-}
-
-static int
-setup_patch(const char *name, const struct shash *args, char **peer_)
-{
- const char *peer;
-
- peer = shash_find_data(args, "peer");
- if (!peer) {
- VLOG_WARN("patch type requires valid 'peer' argument");
- return EINVAL;
- }
-
- if (shash_count(args) > 1) {
- VLOG_WARN("patch type takes only a 'peer' argument");
- return EINVAL;
- }
-
- if (strlen(peer) >= IFNAMSIZ) {
- VLOG_WARN_RL(&rl, "patch 'peer' arg too long");
- return EINVAL;
- }
-
- *peer_ = xstrdup(peer);
- return create_patch(name, peer);
-}
-