goto err2;
}
+ if (iptablesAddUdpOutput(AF_INET, network->def->bridge, 68) < 0) {
+ virReportError(VIR_ERR_SYSTEM_ERROR,
+ _("failed to add iptables rule to allow DHCP replies to '%s'"),
+ network->def->bridge);
+ goto err3;
+ }
+
/* If we are doing local DHCP service on this network, attempt to
* add a rule that will fixup the checksum of DHCP response
* packets back to the guests (but report failure without
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow DNS requests from '%s'"),
network->def->bridge);
- goto err3;
+ goto err4;
}
if (iptablesAddUdpInput(AF_INET, network->def->bridge, 53) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow DNS requests from '%s'"),
network->def->bridge);
- goto err4;
+ goto err5;
}
/* allow TFTP requests through to dnsmasq if necessary */
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow TFTP requests from '%s'"),
network->def->bridge);
- goto err5;
+ goto err6;
}
/* Catch all rules to block forwarding to/from bridges */
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to block outbound traffic from '%s'"),
network->def->bridge);
- goto err6;
+ goto err7;
}
if (iptablesAddForwardRejectIn(AF_INET, network->def->bridge) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to block inbound traffic to '%s'"),
network->def->bridge);
- goto err7;
+ goto err8;
}
/* Allow traffic between guests on the same bridge */
virReportError(VIR_ERR_SYSTEM_ERROR,
_("failed to add iptables rule to allow cross bridge traffic on '%s'"),
network->def->bridge);
- goto err8;
+ goto err9;
}
/* add IPv6 general rules, if needed */
if (networkAddGeneralIp6tablesRules(network) < 0) {
- goto err9;
+ goto err10;
}
return 0;
/* unwind in reverse order from the point of failure */
-err9:
+err10:
iptablesRemoveForwardAllowCross(AF_INET, network->def->bridge);
-err8:
+err9:
iptablesRemoveForwardRejectIn(AF_INET, network->def->bridge);
-err7:
+err8:
iptablesRemoveForwardRejectOut(AF_INET, network->def->bridge);
-err6:
+err7:
if (ipv4def && ipv4def->tftproot) {
iptablesRemoveUdpInput(AF_INET, network->def->bridge, 69);
}
-err5:
+err6:
iptablesRemoveUdpInput(AF_INET, network->def->bridge, 53);
-err4:
+err5:
iptablesRemoveTcpInput(AF_INET, network->def->bridge, 53);
+err4:
+ iptablesRemoveUdpOutput(AF_INET, network->def->bridge, 68);
err3:
iptablesRemoveUdpInput(AF_INET, network->def->bridge, 67);
err2:
if (ipv4def && (ipv4def->nranges || ipv4def->nhosts)) {
iptablesRemoveOutputFixUdpChecksum(network->def->bridge, 68);
}
+ iptablesRemoveUdpOutput(AF_INET, network->def->bridge, 68);
iptablesRemoveUdpInput(AF_INET, network->def->bridge, 67);
iptablesRemoveTcpInput(AF_INET, network->def->bridge, 67);
}
NULL);
}
+static int
+iptablesOutput(int family,
+ const char *iface,
+ int port,
+ int action,
+ int tcp)
+{
+ char portstr[32];
+
+ snprintf(portstr, sizeof(portstr), "%d", port);
+ portstr[sizeof(portstr) - 1] = '\0';
+
+ return iptablesAddRemoveRule("filter", "OUTPUT",
+ family,
+ action,
+ "--out-interface", iface,
+ "--protocol", tcp ? "tcp" : "udp",
+ "--destination-port", portstr,
+ "--jump", "ACCEPT",
+ NULL);
+}
+
/**
* iptablesAddTcpInput:
* @ctx: pointer to the IP table context
return iptablesInput(family, iface, port, REMOVE, 0);
}
+/**
+ * iptablesAddUdpOutput:
+ * @ctx: pointer to the IP table context
+ * @iface: the interface name
+ * @port: the UDP port to add
+ *
+ * Add an output to the IP table allowing access to the given @port from
+ * the given @iface interface for UDP packets
+ *
+ * Returns 0 in case of success or an error code in case of error
+ */
+
+int
+iptablesAddUdpOutput(int family,
+ const char *iface,
+ int port)
+{
+ return iptablesOutput(family, iface, port, ADD, 0);
+}
+
+/**
+ * iptablesRemoveUdpOutput:
+ * @ctx: pointer to the IP table context
+ * @iface: the interface name
+ * @port: the UDP port to remove
+ *
+ * Removes an output from the IP table, hence forbidding access to the given
+ * @port from the given @iface interface for UDP packets
+ *
+ * Returns 0 in case of success or an error code in case of error
+ */
+int
+iptablesRemoveUdpOutput(int family,
+ const char *iface,
+ int port)
+{
+ return iptablesOutput(family, iface, port, REMOVE, 0);
+}
+
static char *iptablesFormatNetwork(virSocketAddr *netaddr,
unsigned int prefix)