2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at:
6 * http://www.apache.org/licenses/LICENSE-2.0
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
17 #include "openvswitch/vlog.h"
18 #include "ovn/lib/ovn-nb-idl.h"
20 VLOG_DEFINE_THIS_MODULE(ovn_util);
23 add_ipv4_netaddr(struct lport_addresses *laddrs, ovs_be32 addr,
26 laddrs->n_ipv4_addrs++;
27 laddrs->ipv4_addrs = xrealloc(laddrs->ipv4_addrs,
28 laddrs->n_ipv4_addrs * sizeof *laddrs->ipv4_addrs);
30 struct ipv4_netaddr *na = &laddrs->ipv4_addrs[laddrs->n_ipv4_addrs - 1];
33 na->mask = be32_prefix_mask(plen);
34 na->network = addr & na->mask;
37 na->addr_s = xasprintf(IP_FMT, IP_ARGS(addr));
38 na->network_s = xasprintf(IP_FMT, IP_ARGS(na->network));
39 na->bcast_s = xasprintf(IP_FMT, IP_ARGS(addr | ~na->mask));
43 add_ipv6_netaddr(struct lport_addresses *laddrs, struct in6_addr addr,
46 laddrs->n_ipv6_addrs++;
47 laddrs->ipv6_addrs = xrealloc(laddrs->ipv6_addrs,
48 laddrs->n_ipv6_addrs * sizeof *laddrs->ipv6_addrs);
50 struct ipv6_netaddr *na = &laddrs->ipv6_addrs[laddrs->n_ipv6_addrs - 1];
52 memcpy(&na->addr, &addr, sizeof na->addr);
53 na->mask = ipv6_create_mask(plen);
54 na->network = ipv6_addr_bitand(&addr, &na->mask);
57 na->addr_s = xmalloc(INET6_ADDRSTRLEN);
58 inet_ntop(AF_INET6, &addr, na->addr_s, INET6_ADDRSTRLEN);
59 na->network_s = xmalloc(INET6_ADDRSTRLEN);
60 inet_ntop(AF_INET6, &na->network, na->network_s, INET6_ADDRSTRLEN);
63 /* Extracts the mac, IPv4 and IPv6 addresses from * 'address' which
64 * should be of the format 'MAC [IP1 IP2 ..]" where IPn should be a
65 * valid IPv4 or IPv6 address and stores them in the 'ipv4_addrs' and
66 * 'ipv6_addrs' fields of 'laddrs'.
68 * Return true if at least 'MAC' is found in 'address', false otherwise.
70 * The caller must call destroy_lport_addresses(). */
72 extract_lsp_addresses(char *address, struct lport_addresses *laddrs)
74 memset(laddrs, 0, sizeof *laddrs);
78 char *buf_end = buf + strlen(address);
79 if (!ovs_scan_len(buf, &buf_index, ETH_ADDR_SCAN_FMT,
80 ETH_ADDR_SCAN_ARGS(laddrs->ea))) {
81 laddrs->ea = eth_addr_zero;
85 laddrs->ea_s = xasprintf(ETH_ADDR_FMT, ETH_ADDR_ARGS(laddrs->ea));
92 /* Loop through the buffer and extract the IPv4/IPv6 addresses
93 * and store in the 'laddrs'. Break the loop if invalid data is found.
96 while (buf < buf_end) {
98 error = ip_parse_cidr_len(buf, &buf_index, &ip4, &plen);
100 add_ipv4_netaddr(laddrs, ip4, plen);
105 error = ipv6_parse_cidr_len(buf, &buf_index, &ip6, &plen);
107 add_ipv6_netaddr(laddrs, ip6, plen);
109 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
110 VLOG_INFO_RL(&rl, "invalid syntax '%s' in address", address);
120 /* Extracts the mac, IPv4 and IPv6 addresses from the
121 * "nbrec_logical_router_port" parameter 'lrp'. Stores the IPv4 and
122 * IPv6 addresses in the 'ipv4_addrs' and 'ipv6_addrs' fields of
123 * 'laddrs', respectively.
125 * Return true if at least 'MAC' is found in 'lrp', false otherwise.
127 * The caller must call destroy_lport_addresses(). */
129 extract_lrp_networks(const struct nbrec_logical_router_port *lrp,
130 struct lport_addresses *laddrs)
132 memset(laddrs, 0, sizeof *laddrs);
134 if (!eth_addr_from_string(lrp->mac, &laddrs->ea)) {
135 laddrs->ea = eth_addr_zero;
138 laddrs->ea_s = xasprintf(ETH_ADDR_FMT, ETH_ADDR_ARGS(laddrs->ea));
140 for (int i = 0; i < lrp->n_networks; i++) {
146 error = ip_parse_cidr(lrp->networks[i], &ip4, &plen);
148 if (!ip4 || plen == 32) {
149 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
150 VLOG_WARN_RL(&rl, "bad 'networks' %s", lrp->networks[i]);
154 add_ipv4_netaddr(laddrs, ip4, plen);
159 error = ipv6_parse_cidr(lrp->networks[i], &ip6, &plen);
162 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
163 VLOG_WARN_RL(&rl, "bad 'networks' %s", lrp->networks[i]);
166 add_ipv6_netaddr(laddrs, ip6, plen);
168 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
169 VLOG_INFO_RL(&rl, "invalid syntax '%s' in networks",
179 destroy_lport_addresses(struct lport_addresses *laddrs)
183 for (int i = 0; i < laddrs->n_ipv4_addrs; i++) {
184 free(laddrs->ipv4_addrs[i].addr_s);
185 free(laddrs->ipv4_addrs[i].network_s);
186 free(laddrs->ipv4_addrs[i].bcast_s);
188 free(laddrs->ipv4_addrs);
190 for (int i = 0; i < laddrs->n_ipv6_addrs; i++) {
191 free(laddrs->ipv6_addrs[i].addr_s);
192 free(laddrs->ipv6_addrs[i].network_s);
194 free(laddrs->ipv6_addrs);
197 /* Allocates a key for NAT conntrack zone allocation for a provided
198 * 'key' record and a 'type'.
200 * It is the caller's responsibility to free the allocated memory. */
202 alloc_nat_zone_key(const char *key, const char *type)
204 return xasprintf("%s_%s", key, type);