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-sb-idl.h"
20 VLOG_DEFINE_THIS_MODULE(ovn_util);
23 * Extracts the mac, ipv4 and ipv6 addresses from the input param 'address'
24 * which should be of the format 'MAC [IP1 IP2 ..]" where IPn should be
25 * a valid IPv4 or IPv6 address and stores them in the 'ipv4_addrs' and
26 * 'ipv6_addrs' fields of input param 'laddrs'. If input param
27 * 'store_ipv6' is true only then extracted ipv6 addresses are stored in
28 * 'ipv6_addrs' fields.
30 * Return true if at least 'MAC' is found in 'address', false otherwise.
32 * The caller must call destroy_lport_addresses().
35 * If 'address' = '00:00:00:00:00:01 10.0.0.4 fe80::ea2a:eaff:fe28:3390/64
36 * 30.0.0.3/23' and 'store_ipv6' = true
37 * then returns true with laddrs->n_ipv4_addrs = 2, naddrs->n_ipv6_addrs = 1.
40 * If 'address' = '00:00:00:00:00:01 10.0.0.4 fe80::ea2a:eaff:fe28:3390/64
41 * 30.0.0.3/23' and 'store_ipv6' = false
42 * then returns true with laddrs->n_ipv4_addrs = 2, naddrs->n_ipv6_addrs = 0.
44 * Eg 3. If 'address' = '00:00:00:00:00:01 10.0.0.4 addr 30.0.0.4', then
45 * returns true with laddrs->n_ipv4_addrs = 1 and laddrs->n_ipv6_addrs = 0.
48 extract_lsp_addresses(char *address, struct lport_addresses *laddrs,
51 memset(laddrs, 0, sizeof *laddrs);
55 char *buf_end = buf + strlen(address);
56 if (!ovs_scan_len(buf, &buf_index, ETH_ADDR_SCAN_FMT,
57 ETH_ADDR_SCAN_ARGS(laddrs->ea))) {
58 laddrs->ea = eth_addr_zero;
62 laddrs->ea_s = xasprintf(ETH_ADDR_FMT, ETH_ADDR_ARGS(laddrs->ea));
69 /* Loop through the buffer and extract the IPv4/IPv6 addresses
70 * and store in the 'laddrs'. Break the loop if invalid data is found.
73 while (buf < buf_end) {
75 error = ip_parse_cidr_len(buf, &buf_index, &ip4, &plen);
77 laddrs->n_ipv4_addrs++;
78 laddrs->ipv4_addrs = xrealloc(laddrs->ipv4_addrs,
79 sizeof (struct ipv4_netaddr) * laddrs->n_ipv4_addrs);
81 struct ipv4_netaddr *na
82 = &laddrs->ipv4_addrs[laddrs->n_ipv4_addrs - 1];
85 na->mask = be32_prefix_mask(plen);
86 na->network = ip4 & na->mask;
89 na->addr_s = xasprintf(IP_FMT, IP_ARGS(ip4));
90 na->network_s = xasprintf(IP_FMT, IP_ARGS(na->network));
91 na->bcast_s = xasprintf(IP_FMT, IP_ARGS(ip4 | ~na->mask));
97 error = ipv6_parse_cidr_len(buf, &buf_index, &ip6, &plen);
98 if (!error && store_ipv6) {
99 laddrs->n_ipv6_addrs++;
100 laddrs->ipv6_addrs = xrealloc(
102 sizeof(struct ipv6_netaddr) * laddrs->n_ipv6_addrs);
104 struct ipv6_netaddr *na
105 = &laddrs->ipv6_addrs[laddrs->n_ipv6_addrs - 1];
107 memcpy(&na->addr, &ip6, sizeof(struct in6_addr));
108 na->mask = ipv6_create_mask(plen);
109 na->network = ipv6_addr_bitand(&ip6, &na->mask);
112 na->addr_s = xmalloc(INET6_ADDRSTRLEN);
113 inet_ntop(AF_INET6, &ip6, na->addr_s, INET6_ADDRSTRLEN);
114 na->network_s = xmalloc(INET6_ADDRSTRLEN);
115 inet_ntop(AF_INET6, &na->network, na->network_s, INET6_ADDRSTRLEN);
119 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
120 VLOG_INFO_RL(&rl, "invalid syntax '%s' in address", address);
131 destroy_lport_addresses(struct lport_addresses *laddrs)
135 for (int i = 0; i < laddrs->n_ipv4_addrs; i++) {
136 free(laddrs->ipv4_addrs[i].addr_s);
137 free(laddrs->ipv4_addrs[i].network_s);
138 free(laddrs->ipv4_addrs[i].bcast_s);
140 free(laddrs->ipv4_addrs);
142 for (int i = 0; i < laddrs->n_ipv6_addrs; i++) {
143 free(laddrs->ipv6_addrs[i].addr_s);
144 free(laddrs->ipv6_addrs[i].network_s);
146 free(laddrs->ipv6_addrs);
149 /* Allocates a key for NAT conntrack zone allocation for a provided
150 * 'key' record and a 'type'.
152 * It is the caller's responsibility to free the allocated memory. */
154 alloc_nat_zone_key(const char *key, const char *type)
156 return xasprintf("%s_%s", key, type);