From 218351dd013213c64d7f0b8bd6df3315c9f1a4a4 Mon Sep 17 00:00:00 2001 From: Ramu Ramamurthy Date: Tue, 26 Apr 2016 17:31:06 -0400 Subject: [PATCH] ovn: Move extract_lport_addresses Move the function extract_lport_addresses to a file in ovn/lib since that function can be used by ovn-controller also to parse addresses stored in the mac column of the port_binding table. Currently that function is used only in ovn_northd. Signed-off-by: Ramu Ramamurthy Signed-off-by: Ben Pfaff --- ovn/lib/automake.mk | 2 + ovn/lib/ovn-util.c | 104 ++++++++++++++++++++++++++++++++++++++++ ovn/lib/ovn-util.h | 44 +++++++++++++++++ ovn/northd/ovn-northd.c | 104 +--------------------------------------- 4 files changed, 151 insertions(+), 103 deletions(-) create mode 100644 ovn/lib/ovn-util.c create mode 100644 ovn/lib/ovn-util.h diff --git a/ovn/lib/automake.mk b/ovn/lib/automake.mk index 9e0935290..2b178da38 100644 --- a/ovn/lib/automake.mk +++ b/ovn/lib/automake.mk @@ -10,6 +10,8 @@ ovn_lib_libovn_la_SOURCES = \ ovn/lib/expr.h \ ovn/lib/lex.c \ ovn/lib/lex.h \ + ovn/lib/ovn-util.c \ + ovn/lib/ovn-util.h \ ovn/lib/logical-fields.h nodist_ovn_lib_libovn_la_SOURCES = \ ovn/lib/ovn-nb-idl.c \ diff --git a/ovn/lib/ovn-util.c b/ovn/lib/ovn-util.c new file mode 100644 index 000000000..abdc247b6 --- /dev/null +++ b/ovn/lib/ovn-util.c @@ -0,0 +1,104 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "ovn-util.h" +#include "openvswitch/vlog.h" + +VLOG_DEFINE_THIS_MODULE(ovn_util); + +/* + * Extracts the mac, ipv4 and ipv6 addresses from the input param 'address' + * which should be of the format 'MAC [IP1 IP2 ..]" where IPn should be + * a valid IPv4 or IPv6 address and stores them in the 'ipv4_addrs' and + * 'ipv6_addrs' fields of input param 'laddrs'. + * The caller has to free the 'ipv4_addrs' and 'ipv6_addrs' fields. + * If input param 'store_ipv6' is true only then extracted ipv6 addresses + * are stored in 'ipv6_addrs' fields. + * Return true if at least 'MAC' is found in 'address', false otherwise. + * Eg 1. + * If 'address' = '00:00:00:00:00:01 10.0.0.4 fe80::ea2a:eaff:fe28:3390/64 + * 30.0.0.3/23' and 'store_ipv6' = true + * then returns true with laddrs->n_ipv4_addrs = 2, naddrs->n_ipv6_addrs = 1. + * + * Eg. 2 + * If 'address' = '00:00:00:00:00:01 10.0.0.4 fe80::ea2a:eaff:fe28:3390/64 + * 30.0.0.3/23' and 'store_ipv6' = false + * then returns true with laddrs->n_ipv4_addrs = 2, naddrs->n_ipv6_addrs = 0. + * + * Eg 3. If 'address' = '00:00:00:00:00:01 10.0.0.4 addr 30.0.0.4', then + * returns true with laddrs->n_ipv4_addrs = 1 and laddrs->n_ipv6_addrs = 0. + */ +bool +extract_lport_addresses(char *address, struct lport_addresses *laddrs, + bool store_ipv6) +{ + char *buf = address; + int buf_index = 0; + char *buf_end = buf + strlen(address); + if (!ovs_scan_len(buf, &buf_index, ETH_ADDR_SCAN_FMT, + ETH_ADDR_SCAN_ARGS(laddrs->ea))) { + return false; + } + + ovs_be32 ip4; + struct in6_addr ip6; + unsigned int plen; + char *error; + + laddrs->n_ipv4_addrs = 0; + laddrs->n_ipv6_addrs = 0; + laddrs->ipv4_addrs = NULL; + laddrs->ipv6_addrs = NULL; + + /* Loop through the buffer and extract the IPv4/IPv6 addresses + * and store in the 'laddrs'. Break the loop if invalid data is found. + */ + buf += buf_index; + while (buf < buf_end) { + buf_index = 0; + error = ip_parse_cidr_len(buf, &buf_index, &ip4, &plen); + if (!error) { + laddrs->n_ipv4_addrs++; + laddrs->ipv4_addrs = xrealloc( + laddrs->ipv4_addrs, + sizeof (struct ipv4_netaddr) * laddrs->n_ipv4_addrs); + laddrs->ipv4_addrs[laddrs->n_ipv4_addrs - 1].addr = ip4; + laddrs->ipv4_addrs[laddrs->n_ipv4_addrs - 1].plen = plen; + buf += buf_index; + continue; + } + free(error); + error = ipv6_parse_cidr_len(buf, &buf_index, &ip6, &plen); + if (!error && store_ipv6) { + laddrs->n_ipv6_addrs++; + laddrs->ipv6_addrs = xrealloc( + laddrs->ipv6_addrs, + sizeof(struct ipv6_netaddr) * laddrs->n_ipv6_addrs); + memcpy(&laddrs->ipv6_addrs[laddrs->n_ipv6_addrs - 1].addr, &ip6, + sizeof(struct in6_addr)); + laddrs->ipv6_addrs[laddrs->n_ipv6_addrs - 1].plen = plen; + } + + if (error) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); + VLOG_INFO_RL(&rl, "invalid syntax '%s' in address", address); + free(error); + break; + } + buf += buf_index; + } + + return true; +} diff --git a/ovn/lib/ovn-util.h b/ovn/lib/ovn-util.h new file mode 100644 index 000000000..242984ae2 --- /dev/null +++ b/ovn/lib/ovn-util.h @@ -0,0 +1,44 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef OVN_UTIL_H +#define OVN_UTIL_H 1 + +#include "lib/packets.h" + +struct ipv4_netaddr { + ovs_be32 addr; + unsigned int plen; +}; + +struct ipv6_netaddr { + struct in6_addr addr; + unsigned int plen; +}; + +struct lport_addresses { + struct eth_addr ea; + size_t n_ipv4_addrs; + struct ipv4_netaddr *ipv4_addrs; + size_t n_ipv6_addrs; + struct ipv6_netaddr *ipv6_addrs; +}; + +bool +extract_lport_addresses(char *address, struct lport_addresses *laddrs, + bool store_ipv6); + + +#endif diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index 9e036065f..44e9430e4 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -29,6 +29,7 @@ #include "ovn/lib/lex.h" #include "ovn/lib/ovn-nb-idl.h" #include "ovn/lib/ovn-sb-idl.h" +#include "ovn/lib/ovn-util.h" #include "packets.h" #include "poll-loop.h" #include "smap.h" @@ -955,109 +956,6 @@ ovn_lflow_destroy(struct hmap *lflows, struct ovn_lflow *lflow) } } -struct ipv4_netaddr { - ovs_be32 addr; - unsigned int plen; -}; - -struct ipv6_netaddr { - struct in6_addr addr; - unsigned int plen; -}; - -struct lport_addresses { - struct eth_addr ea; - size_t n_ipv4_addrs; - struct ipv4_netaddr *ipv4_addrs; - size_t n_ipv6_addrs; - struct ipv6_netaddr *ipv6_addrs; -}; - -/* - * Extracts the mac, ipv4 and ipv6 addresses from the input param 'address' - * which should be of the format 'MAC [IP1 IP2 ..]" where IPn should be - * a valid IPv4 or IPv6 address and stores them in the 'ipv4_addrs' and - * 'ipv6_addrs' fields of input param 'laddrs'. - * The caller has to free the 'ipv4_addrs' and 'ipv6_addrs' fields. - * If input param 'store_ipv6' is true only then extracted ipv6 addresses - * are stored in 'ipv6_addrs' fields. - * Return true if at least 'MAC' is found in 'address', false otherwise. - * Eg 1. - * If 'address' = '00:00:00:00:00:01 10.0.0.4 fe80::ea2a:eaff:fe28:3390/64 - * 30.0.0.3/23' and 'store_ipv6' = true - * then returns true with laddrs->n_ipv4_addrs = 2, naddrs->n_ipv6_addrs = 1. - * - * Eg. 2 - * If 'address' = '00:00:00:00:00:01 10.0.0.4 fe80::ea2a:eaff:fe28:3390/64 - * 30.0.0.3/23' and 'store_ipv6' = false - * then returns true with laddrs->n_ipv4_addrs = 2, naddrs->n_ipv6_addrs = 0. - * - * Eg 3. If 'address' = '00:00:00:00:00:01 10.0.0.4 addr 30.0.0.4', then - * returns true with laddrs->n_ipv4_addrs = 1 and laddrs->n_ipv6_addrs = 0. - */ -static bool -extract_lport_addresses(char *address, struct lport_addresses *laddrs, - bool store_ipv6) -{ - char *buf = address; - int buf_index = 0; - char *buf_end = buf + strlen(address); - if (!ovs_scan_len(buf, &buf_index, ETH_ADDR_SCAN_FMT, - ETH_ADDR_SCAN_ARGS(laddrs->ea))) { - return false; - } - - ovs_be32 ip4; - struct in6_addr ip6; - unsigned int plen; - char *error; - - laddrs->n_ipv4_addrs = 0; - laddrs->n_ipv6_addrs = 0; - laddrs->ipv4_addrs = NULL; - laddrs->ipv6_addrs = NULL; - - /* Loop through the buffer and extract the IPv4/IPv6 addresses - * and store in the 'laddrs'. Break the loop if invalid data is found. - */ - buf += buf_index; - while (buf < buf_end) { - buf_index = 0; - error = ip_parse_cidr_len(buf, &buf_index, &ip4, &plen); - if (!error) { - laddrs->n_ipv4_addrs++; - laddrs->ipv4_addrs = xrealloc( - laddrs->ipv4_addrs, - sizeof (struct ipv4_netaddr) * laddrs->n_ipv4_addrs); - laddrs->ipv4_addrs[laddrs->n_ipv4_addrs - 1].addr = ip4; - laddrs->ipv4_addrs[laddrs->n_ipv4_addrs - 1].plen = plen; - buf += buf_index; - continue; - } - free(error); - error = ipv6_parse_cidr_len(buf, &buf_index, &ip6, &plen); - if (!error && store_ipv6) { - laddrs->n_ipv6_addrs++; - laddrs->ipv6_addrs = xrealloc( - laddrs->ipv6_addrs, - sizeof(struct ipv6_netaddr) * laddrs->n_ipv6_addrs); - memcpy(&laddrs->ipv6_addrs[laddrs->n_ipv6_addrs - 1].addr, &ip6, - sizeof(struct in6_addr)); - laddrs->ipv6_addrs[laddrs->n_ipv6_addrs - 1].plen = plen; - } - - if (error) { - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); - VLOG_INFO_RL(&rl, "invalid syntax '%s' in address", address); - free(error); - break; - } - buf += buf_index; - } - - return true; -} - /* Appends port security constraints on L2 address field 'eth_addr_field' * (e.g. "eth.src" or "eth.dst") to 'match'. 'port_security', with * 'n_port_security' elements, is the collection of port_security constraints -- 2.20.1