static char *iptablesFormatNetwork(virSocketAddr *netaddr,
                                   unsigned int prefix)
{
    virSocketAddr network;
    char *netstr;
    char *ret;

    if (!(VIR_SOCKET_ADDR_IS_FAMILY(netaddr, AF_INET) ||
          VIR_SOCKET_ADDR_IS_FAMILY(netaddr, AF_INET6))) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Only IPv4 or IPv6 addresses can be used with iptables"));
        return NULL;
    }

    if (virSocketAddrMaskByPrefix(netaddr, prefix, &network) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Failure to mask address"));
        return NULL;
    }

    netstr = virSocketAddrFormat(&network);

    if (!netstr)
        return NULL;

    if (virAsprintf(&ret, "%s/%d", netstr, prefix) < 0)
        virReportOOMError();

    VIR_FREE(netstr);
    return ret;
}
Exemple #2
0
static int testMaskNetwork(const char *addrstr,
                           int prefix,
                           const char *networkstr)
{
    virSocketAddr addr;
    virSocketAddr network;
    char *gotnet = NULL;

    /* Intentionally fill with garbage */
    memset(&network, 1, sizeof(network));

    if (virSocketAddrParse(&addr, addrstr, AF_UNSPEC) < 0)
        return -1;

    if (virSocketAddrMaskByPrefix(&addr, prefix, &network) < 0)
        return -1;

    if (!(gotnet = virSocketAddrFormat(&network)))
        return -1;

    if (STRNEQ(networkstr, gotnet)) {
        VIR_FREE(gotnet);
        fprintf(stderr, "Expected %s, got %s\n", networkstr, gotnet);
        return -1;
    }
    VIR_FREE(gotnet);
    return 0;
}
Exemple #3
0
virNetDevIPRoutePtr
virNetDevIPRouteCreate(const char *errorDetail,
                       const char *family,
                       const char *address,
                       const char *netmask,
                       const char *gateway,
                       unsigned int prefix,
                       bool hasPrefix,
                       unsigned int metric,
                       bool hasMetric)
{
    virNetDevIPRoutePtr def = NULL;
    virSocketAddr testAddr;

    if (VIR_ALLOC(def) < 0)
        return NULL;

    if (VIR_STRDUP(def->family, family) < 0)
        goto error;

    def->prefix = prefix;
    def->has_prefix = hasPrefix;
    def->metric = metric;
    def->has_metric = hasMetric;

    /* Note: both network and gateway addresses must be specified */

    if (!address) {
        virReportError(VIR_ERR_XML_ERROR,
                       _("%s: Missing required address attribute "
                         "in route definition"),
                       errorDetail);
        goto error;
    }

    if (!gateway) {
        virReportError(VIR_ERR_XML_ERROR,
                       _("%s: Missing required gateway attribute "
                         "in route definition"),
                       errorDetail);
        goto error;
    }

    if (virSocketAddrParse(&def->address, address, AF_UNSPEC) < 0) {
        virReportError(VIR_ERR_XML_ERROR,
                       _("%s: Bad network address '%s' "
                         "in route definition"),
                       errorDetail, address);
        goto error;
    }

    if (virSocketAddrParse(&def->gateway, gateway, AF_UNSPEC) < 0) {
        virReportError(VIR_ERR_XML_ERROR,
                       _("%s: Bad gateway address '%s' "
                         "in route definition"),
                       errorDetail, gateway);
        goto error;
    }

    /* validate network address, etc. for each family */
    if ((def->family == NULL) || (STREQ(def->family, "ipv4"))) {
        if (!(VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) ||
              VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_UNSPEC))) {
            virReportError(VIR_ERR_XML_ERROR,
                           def->family == NULL ?
                           _("%s: No family specified for non-IPv4 address '%s' "
                             "in route definition") :
                           _("%s: IPv4 family specified for non-IPv4 address '%s' "
                             "in route definition"),
                           errorDetail, address);
            goto error;
        }
        if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET)) {
            virReportError(VIR_ERR_XML_ERROR,
                           def->family == NULL ?
                           _("%s: No family specified for non-IPv4 gateway '%s' "
                             "in route definition") :
                           _("%s: IPv4 family specified for non-IPv4 gateway '%s' "
                             "in route definition"),
                           errorDetail, address);
            goto error;
        }
        if (netmask) {
            if (virSocketAddrParse(&def->netmask, netmask, AF_UNSPEC) < 0) {
                virReportError(VIR_ERR_XML_ERROR,
                               _("%s: Bad netmask address '%s' "
                                 "in route definition"),
                               errorDetail, netmask);
                goto error;
            }
            if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->netmask, AF_INET)) {
                virReportError(VIR_ERR_XML_ERROR,
                               _("%s: Invalid netmask '%s' "
                                 "for address '%s' (both must be IPv4)"),
                               errorDetail, netmask, address);
                goto error;
            }
            if (def->has_prefix) {
                /* can't have both netmask and prefix at the same time */
                virReportError(VIR_ERR_XML_ERROR,
                               _("%s: Route definition cannot have both "
                                 "a prefix and a netmask"),
                               errorDetail);
                goto error;
            }
        }
        if (def->prefix > 32) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("%s: Invalid prefix %u specified "
                             "in route definition, "
                             "must be 0 - 32"),
                           errorDetail, def->prefix);
            goto error;
        }
    } else if (STREQ(def->family, "ipv6")) {
        if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("%s: ipv6 family specified for non-IPv6 address '%s' "
                             "in route definition"),
                           errorDetail, address);
            goto error;
        }
        if (netmask) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("%s: Specifying netmask invalid for IPv6 address '%s' "
                             "in route definition"),
                           errorDetail, address);
            goto error;
        }
        if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET6)) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("%s: ipv6 specified for non-IPv6 gateway address '%s' "
                             "in route definition"),
                           errorDetail, gateway);
            goto error;
        }
        if (def->prefix > 128) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("%s: Invalid prefix %u specified "
                             "in route definition, "
                             "must be 0 - 128"),
                           errorDetail, def->prefix);
            goto error;
        }
    } else {
        virReportError(VIR_ERR_XML_ERROR,
                       _("%s: Unrecognized family '%s' "
                         "in route definition"),
                       errorDetail, def->family);
        goto error;
    }

    /* make sure the address is a network address */
    if (netmask) {
        if (virSocketAddrMask(&def->address, &def->netmask, &testAddr) < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("%s: Error converting address '%s' with netmask '%s' "
                             "to network-address "
                             "in route definition"),
                           errorDetail, address, netmask);
            goto error;
        }
    } else {
        if (virSocketAddrMaskByPrefix(&def->address,
                                      def->prefix, &testAddr) < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("%s: Error converting address '%s' with prefix %u "
                             "to network-address "
                             "in route definition"),
                           errorDetail, address, def->prefix);
            goto error;
        }
    }
    if (!virSocketAddrEqual(&def->address, &testAddr)) {
        virReportError(VIR_ERR_XML_ERROR,
                       _("%s: Address '%s' in route definition "
                         "is not a network address"),
                       errorDetail, address);
        goto error;
    }

    return def;

 error:
    virNetDevIPRouteFree(def);
    return NULL;
}