On Fri, Mar 10, 2017 at 07:46:58AM +0530, [email protected] wrote:
> From: Numan Siddique <[email protected]>
>
> If the CMS wants to make use of ovn ipam it can now provide a
> list of IPv4 addresses and a range of IPv4 addresses which
> will be excluded from the dynamic address assignment.
> To support this, a new option 'exclude_ips' is added in the
> Logical_switch.other_config column.
>
> Eg. ovn-nbctl set Logical_switch sw0
> other_config:exclude_ips="10.0.0.2 10.0.0.30..10.0.0.40"
>
> The present code, uses hash maps to store the assigned IP addresses.
> In order to support this option, this patch has refactored the IPAM
> assignment. It now uses a bitmap to manage the IP assignment with
> each bit in the bitmap representing an IPv4 address.
>
> This patch also clears the 'Logical_switch_port.dynamic_addresses'
> if the CMS has cleared 'dynamic' address assignment request.
>
> Signed-off-by: Numan Siddique <[email protected]>
Thanks a lot for working on this! I apologize that it took a long time
to review it.
I'm going to apply this to master in a few minutes. I'm folding in the
following.
diff --git a/NEWS b/NEWS
index 05af97a1f030..8607b04b6ed5 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ Post-v2.7.0
- New support for multiple VLANs (802.1ad or "QinQ"), including a new
"dot1q-tunnel" port VLAN mode.
- OVN:
+ * IPAM for IPv4 can now exclude user-defined addresses from assignment.
* Make the DHCPv4 router setting optional.
* Gratuitous ARP for NAT addresses on a distributed logical router.
* Allow ovn-controller SSL configuration to be obtained from vswitchd
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index 390a8bbad641..878fb7295e33 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -544,40 +544,40 @@ init_ipam_info_for_datapath(struct ovn_datapath *od)
/* exclude_ip_list could be in the format -
* "10.0.0.4 10.0.0.10 10.0.0.20..10.0.0.50 10.0.0.100..10.0.0.110".
*/
- while(lexer_get(&lexer) || lexer.error) {
+ lexer_get(&lexer);
+ while (lexer.token.type != LEX_T_END) {
if (lexer.token.type != LEX_T_INTEGER) {
+ lexer_syntax_error(&lexer, "expecting address");
break;
}
- uint32_t start_ipv4 = 0;
- uint32_t end_ipv4 = 0;
+ uint32_t start = ntohl(lexer.token.value.ipv4);
+ lexer_get(&lexer);
- start_ipv4 = ntohl(lexer.token.value.ipv4);
- if(lexer_lookahead(&lexer) == LEX_T_ELLIPSIS) {
- lexer_get(&lexer);
- lexer_get(&lexer);
+ uint32_t end = start + 1;
+ if (lexer_match(&lexer, LEX_T_ELLIPSIS)) {
if (lexer.token.type != LEX_T_INTEGER) {
+ lexer_syntax_error(&lexer, "expecting address range");
break;
}
- end_ipv4 = ntohl(lexer.token.value.ipv4);
- }
-
- /* Validate start_ipv4. */
- if ((end_ipv4 && start_ipv4 > end_ipv4) ||
- start_ipv4 < od->ipam_info->start_ipv4 ||
- start_ipv4 > (od->ipam_info->start_ipv4 +
- od->ipam_info->total_ipv4s)) {
- /* Invalid format. Continue so we can parse further.*/
- continue;
+ end = ntohl(lexer.token.value.ipv4) + 1;
+ lexer_get(&lexer);
}
- if (end_ipv4 > (
- od->ipam_info->start_ipv4 + od->ipam_info->total_ipv4s)) {
- continue;
+ /* Clamp start...end to fit the subnet. */
+ start = MAX(od->ipam_info->start_ipv4, start);
+ end = MIN(od->ipam_info->start_ipv4 + od->ipam_info->total_ipv4s, end);
+ if (end > start) {
+ bitmap_set_multiple(od->ipam_info->allocated_ipv4s,
+ start - od->ipam_info->start_ipv4,
+ end - start, 1);
+ } else {
+ lexer_error(&lexer, "excluded addresses not in subnet");
}
-
- size_t count = end_ipv4 ? (end_ipv4 - start_ipv4) + 1 : 1;
- bitmap_set_multiple(od->ipam_info->allocated_ipv4s,
- start_ipv4 - od->ipam_info->start_ipv4, count, 1);
+ }
+ if (lexer.error) {
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
+ VLOG_WARN_RL(&rl, "logical switch "UUID_FMT": bad exclude_ips (%s)",
+ UUID_ARGS(&od->key), lexer.error);
}
lexer_destroy(&lexer);
}
@@ -894,7 +894,8 @@ ipam_insert_ip(struct ovn_datapath *od, uint32_t ip)
if (ip >= od->ipam_info->start_ipv4 &&
ip < (od->ipam_info->start_ipv4 + od->ipam_info->total_ipv4s)) {
- bitmap_set1(od->ipam_info->allocated_ipv4s, ip -
od->ipam_info->start_ipv4);
+ bitmap_set1(od->ipam_info->allocated_ipv4s,
+ ip - od->ipam_info->start_ipv4);
}
}
diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
index 75a249a9eb2b..68a00392760a 100644
--- a/ovn/ovn-nb.xml
+++ b/ovn/ovn-nb.xml
@@ -134,26 +134,35 @@
QOS marking rules that apply to packets within the logical switch.
</column>
- <group title="other_config">
+ <group title="IP Address Assignment">
<p>
- Additional configuration options for the logical switch.
+ These options control automatic IP address management (IPAM) for ports
+ attached to the logical switch. To enable IPAM, set <ref
+ column="other_config" key="subnet"/> and optionally <ref
+ column="other_config:exclude_ips"/>. Then, to request dynamic address
+ assignment for a particular port, use the <code>dynamic</code> keyword
+ in the <ref table="Logical_Switch_Port" column="addresses"/> column of
+ the port's <ref table="Logical_Switch_Port"/> row.
</p>
<column name="other_config" key="subnet">
Set this to an IPv4 subnet, e.g. <code>192.168.0.0/24</code>, to enable
<code>ovn-northd</code> to automatically assign IP addresses within
- that subnet. Use the <code>dynamic</code> keyword in the <ref
- table="Logical_Switch_Port"/> table's <ref table="Logical_Switch_Port"
- column="addresses"/> column to request dynamic address assignment for a
- particular port.
+ that subnet.
</column>
<column name="other_config" key="exclude_ips">
- Set this to a list of IPv4 addresses from the subnet if defined in the
- <ref table="Logical_Switch_Port"/> table's <ref
table="Logical_Switch_Port"
- column="other_config:subnet"/> column. The defined list of IPs will
- be excluded from the dynamic address assignment. A range can also be
- specified.
+ <p>
+ To exclude some addresses from automatic IP address management, set
+ this to a list of the IPv4 addresses or <code>..</code>-delimited
+ ranges to exclude. The addresses or ranges should be a subset of
+ those in <ref column="other_config" key="subnet"/>.
+ </p>
+ <p>
+ Whether listed or not, <code>ovn-northd</code> will never allocate
+ the first or last address in a subnet, such as 192.168.0.0 or
+ 192.168.0.255 in 192.168.0.0/24.
+ </p>
<p>
Examples:
</p>
@@ -1438,7 +1447,7 @@
<column name="options" key="lease_time"
type='{"type": "integer", "minInteger": 0, "maxInteger":
4294967295}'>
<p>
- The offered lease time in seconds,
+ The offered lease time in seconds,
</p>
<p>
--
2.10.2
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev