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.
18 #include "openvswitch/vlog.h"
19 #include "ovn/lib/ovn-nb-idl.h"
21 VLOG_DEFINE_THIS_MODULE(ovn_util
);
24 add_ipv4_netaddr(struct lport_addresses
*laddrs
, ovs_be32 addr
,
27 laddrs
->n_ipv4_addrs
++;
28 laddrs
->ipv4_addrs
= xrealloc(laddrs
->ipv4_addrs
,
29 laddrs
->n_ipv4_addrs
* sizeof *laddrs
->ipv4_addrs
);
31 struct ipv4_netaddr
*na
= &laddrs
->ipv4_addrs
[laddrs
->n_ipv4_addrs
- 1];
34 na
->mask
= be32_prefix_mask(plen
);
35 na
->network
= addr
& na
->mask
;
38 ovs_be32 bcast
= addr
| ~na
->mask
;
39 inet_ntop(AF_INET
, &addr
, na
->addr_s
, sizeof na
->addr_s
);
40 inet_ntop(AF_INET
, &na
->network
, na
->network_s
, sizeof na
->network_s
);
41 inet_ntop(AF_INET
, &bcast
, na
->bcast_s
, sizeof na
->bcast_s
);
45 add_ipv6_netaddr(struct lport_addresses
*laddrs
, struct in6_addr addr
,
48 laddrs
->n_ipv6_addrs
++;
49 laddrs
->ipv6_addrs
= xrealloc(laddrs
->ipv6_addrs
,
50 laddrs
->n_ipv6_addrs
* sizeof *laddrs
->ipv6_addrs
);
52 struct ipv6_netaddr
*na
= &laddrs
->ipv6_addrs
[laddrs
->n_ipv6_addrs
- 1];
54 memcpy(&na
->addr
, &addr
, sizeof na
->addr
);
55 na
->mask
= ipv6_create_mask(plen
);
56 na
->network
= ipv6_addr_bitand(&addr
, &na
->mask
);
58 in6_addr_solicited_node(&na
->sn_addr
, &addr
);
60 inet_ntop(AF_INET6
, &addr
, na
->addr_s
, sizeof na
->addr_s
);
61 inet_ntop(AF_INET6
, &na
->sn_addr
, na
->sn_addr_s
, sizeof na
->sn_addr_s
);
62 inet_ntop(AF_INET6
, &na
->network
, na
->network_s
, sizeof na
->network_s
);
65 /* Returns true if specified address specifies a dynamic address,
66 * supporting the following formats:
69 * Both MAC and IP are to be allocated dynamically.
71 * "xx:xx:xx:xx:xx:xx dynamic":
72 * Use specified MAC address, but allocate an IP address
76 is_dynamic_lsp_address(const char *address
)
80 return (!strcmp(address
, "dynamic")
81 || (ovs_scan(address
, ETH_ADDR_SCAN_FMT
" dynamic%n",
82 ETH_ADDR_SCAN_ARGS(ea
), &n
) && address
[n
] == '\0'));
85 /* Extracts the mac, IPv4 and IPv6 addresses from * 'address' which
86 * should be of the format 'MAC [IP1 IP2 ..]" where IPn should be a
87 * valid IPv4 or IPv6 address and stores them in the 'ipv4_addrs' and
88 * 'ipv6_addrs' fields of 'laddrs'.
90 * Return true if at least 'MAC' is found in 'address', false otherwise.
92 * The caller must call destroy_lport_addresses(). */
94 extract_lsp_addresses(const char *address
, struct lport_addresses
*laddrs
)
96 memset(laddrs
, 0, sizeof *laddrs
);
98 const char *buf
= address
;
100 const char *buf_end
= buf
+ strlen(address
);
101 if (!ovs_scan_len(buf
, &buf_index
, ETH_ADDR_SCAN_FMT
,
102 ETH_ADDR_SCAN_ARGS(laddrs
->ea
))) {
103 laddrs
->ea
= eth_addr_zero
;
107 snprintf(laddrs
->ea_s
, sizeof laddrs
->ea_s
, ETH_ADDR_FMT
,
108 ETH_ADDR_ARGS(laddrs
->ea
));
115 /* Loop through the buffer and extract the IPv4/IPv6 addresses
116 * and store in the 'laddrs'. Break the loop if invalid data is found.
119 while (buf
< buf_end
) {
121 error
= ip_parse_cidr_len(buf
, &buf_index
, &ip4
, &plen
);
123 add_ipv4_netaddr(laddrs
, ip4
, plen
);
128 error
= ipv6_parse_cidr_len(buf
, &buf_index
, &ip6
, &plen
);
130 add_ipv6_netaddr(laddrs
, ip6
, plen
);
132 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 1);
133 VLOG_INFO_RL(&rl
, "invalid syntax '%s' in address", address
);
143 /* Extracts the mac, IPv4 and IPv6 addresses from the
144 * "nbrec_logical_router_port" parameter 'lrp'. Stores the IPv4 and
145 * IPv6 addresses in the 'ipv4_addrs' and 'ipv6_addrs' fields of
146 * 'laddrs', respectively. In addition, a link local IPv6 address
147 * based on the 'mac' member of 'lrp' is added to the 'ipv6_addrs'
150 * Return true if a valid 'mac' address is found in 'lrp', false otherwise.
152 * The caller must call destroy_lport_addresses(). */
154 extract_lrp_networks(const struct nbrec_logical_router_port
*lrp
,
155 struct lport_addresses
*laddrs
)
157 memset(laddrs
, 0, sizeof *laddrs
);
159 if (!eth_addr_from_string(lrp
->mac
, &laddrs
->ea
)) {
160 laddrs
->ea
= eth_addr_zero
;
163 snprintf(laddrs
->ea_s
, sizeof laddrs
->ea_s
, ETH_ADDR_FMT
,
164 ETH_ADDR_ARGS(laddrs
->ea
));
166 for (int i
= 0; i
< lrp
->n_networks
; i
++) {
172 error
= ip_parse_cidr(lrp
->networks
[i
], &ip4
, &plen
);
174 if (!ip4
|| plen
== 32) {
175 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(5, 1);
176 VLOG_WARN_RL(&rl
, "bad 'networks' %s", lrp
->networks
[i
]);
180 add_ipv4_netaddr(laddrs
, ip4
, plen
);
185 error
= ipv6_parse_cidr(lrp
->networks
[i
], &ip6
, &plen
);
188 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(5, 1);
189 VLOG_WARN_RL(&rl
, "bad 'networks' %s", lrp
->networks
[i
]);
192 add_ipv6_netaddr(laddrs
, ip6
, plen
);
194 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 1);
195 VLOG_INFO_RL(&rl
, "invalid syntax '%s' in networks",
201 /* Always add the IPv6 link local address. */
203 in6_generate_lla(laddrs
->ea
, &lla
);
204 add_ipv6_netaddr(laddrs
, lla
, 64);
210 destroy_lport_addresses(struct lport_addresses
*laddrs
)
212 free(laddrs
->ipv4_addrs
);
213 free(laddrs
->ipv6_addrs
);
216 /* Allocates a key for NAT conntrack zone allocation for a provided
217 * 'key' record and a 'type'.
219 * It is the caller's responsibility to free the allocated memory. */
221 alloc_nat_zone_key(const struct uuid
*key
, const char *type
)
223 return xasprintf(UUID_FMT
"_%s", UUID_ARGS(key
), type
);
231 def
= getenv("OVN_NB_DB");
233 def
= xasprintf("unix:%s/ovnnb_db.sock", ovs_rundir());
244 def
= getenv("OVN_SB_DB");
246 def
= xasprintf("unix:%s/ovnsb_db.sock", ovs_rundir());