Message ID | 1603374334-4360-1-git-send-email-dceara@redhat.com |
---|---|
State | Accepted |
Headers | show |
Series | [ovs-dev] ovn-util: Remove redundant struct v46_ip. | expand |
Bleep bloop. Greetings Dumitru Ceara, I am a robot and I have tried out your patch. Thanks for your contribution. I encountered some error that I wasn't expecting. See the details below. build: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./ovn -I ./include -I ./lib -I ./lib -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -MT controller/pinctrl.o -MD -MP -MF $depbase.Tpo -c -o controller/pinctrl.o controller/pinctrl.c &&\ mv -f $depbase.Tpo $depbase.Po depbase=`echo controller/patch.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\ gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./ovn -I ./include -I ./lib -I ./lib -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -MT controller/patch.o -MD -MP -MF $depbase.Tpo -c -o controller/patch.o controller/patch.c &&\ mv -f $depbase.Tpo $depbase.Po depbase=`echo controller/ovn-controller.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\ gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./ovn -I ./include -I ./lib -I ./lib -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -MT controller/ovn-controller.o -MD -MP -MF $depbase.Tpo -c -o controller/ovn-controller.o controller/ovn-controller.c &&\ mv -f $depbase.Tpo $depbase.Po depbase=`echo controller/physical.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\ gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./include -I ./ovn -I ./include -I ./lib -I ./lib -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/include -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR/lib -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -I /var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace/OVSDIR -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -MT controller/physical.o -MD -MP -MF $depbase.Tpo -c -o controller/physical.o controller/physical.c &&\ mv -f $depbase.Tpo $depbase.Po controller/physical.c: In function ‘put_remote_port_redirect_overlay’: controller/physical.c:387:23: error: ‘struct ofpact_bundle’ has no member named ‘n_slaves’ if (bundle->n_slaves >= BUNDLE_MAX_SLAVES) { ^ controller/physical.c:387:37: error: ‘BUNDLE_MAX_SLAVES’ undeclared (first use in this function) if (bundle->n_slaves >= BUNDLE_MAX_SLAVES) { ^ controller/physical.c:387:37: note: each undeclared identifier is reported only once for each function it appears in controller/physical.c:395:19: error: ‘struct ofpact_bundle’ has no member named ‘n_slaves’ bundle->n_slaves++; ^ make[1]: *** [controller/physical.o] Error 1 make[1]: Leaving directory `/var/lib/jenkins/jobs/0day_robot_upstream_build_ovn_from_pw/workspace' make: *** [all] Error 2 Please check this out. If you feel there has been an error, please email aconole@redhat.com Thanks, 0-day Robot
On Thu, Oct 22, 2020 at 7:16 PM Dumitru Ceara <dceara@redhat.com> wrote: > > Use struct in6_addr instead and IPv4-mapped IPs. > > Reported-at: https://mail.openvswitch.org/pipermail/ovs-dev/2020-October/376160.html > Fixes: 719f586e4d38 ("northd: Add lflows for IPv6 NAT.") > Suggested-by: Ilya Maximets <i.maximets@ovn.org> > Signed-off-by: Dumitru Ceara <dceara@redhat.com> Thanks Dumitru. I applied this patch to master. Numan > --- > ic/ovn-ic.c | 112 ++++++++++++++++++++++++++++---------------------- > lib/ovn-util.c | 31 +++++--------- > lib/ovn-util.h | 15 ++----- > northd/ovn-northd.c | 38 ++++++++--------- > utilities/ovn-nbctl.c | 4 +- > 5 files changed, 99 insertions(+), 101 deletions(-) > > diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c > index 923969f..ba28bc9 100644 > --- a/ic/ovn-ic.c > +++ b/ic/ovn-ic.c > @@ -817,9 +817,9 @@ struct ic_router_info { > /* Represents an interconnection route entry. */ > struct ic_route_info { > struct hmap_node node; > - struct v46_ip prefix; > + struct in6_addr prefix; > unsigned int plen; > - struct v46_ip nexthop; > + struct in6_addr nexthop; > > /* Either nb_route or nb_lrp is set and the other one must be NULL. > * - For a route that is learned from IC-SB, or a static route that is > @@ -832,23 +832,23 @@ struct ic_route_info { > }; > > static uint32_t > -ic_route_hash(const struct v46_ip *prefix, unsigned int plen, > - const struct v46_ip *nexthop) > +ic_route_hash(const struct in6_addr *prefix, unsigned int plen, > + const struct in6_addr *nexthop) > { > uint32_t basis = hash_bytes(prefix, sizeof *prefix, (uint32_t)plen); > return hash_bytes(nexthop, sizeof *nexthop, basis); > } > > static struct ic_route_info * > -ic_route_find(struct hmap *routes, const struct v46_ip *prefix, > - unsigned int plen, const struct v46_ip *nexthop) > +ic_route_find(struct hmap *routes, const struct in6_addr *prefix, > + unsigned int plen, const struct in6_addr *nexthop) > { > struct ic_route_info *r; > uint32_t hash = ic_route_hash(prefix, plen, nexthop); > HMAP_FOR_EACH_WITH_HASH (r, node, hash, routes) { > - if (ip46_equals(&r->prefix, prefix) && > + if (ipv6_addr_equals(&r->prefix, prefix) && > r->plen == plen && > - ip46_equals(&r->nexthop, nexthop)) { > + ipv6_addr_equals(&r->nexthop, nexthop)) { > return r; > } > } > @@ -870,8 +870,8 @@ ic_router_find(struct hmap *ic_lrs, const struct nbrec_logical_router *lr) > > static bool > parse_route(const char *s_prefix, const char *s_nexthop, > - struct v46_ip *prefix, unsigned int *plen, > - struct v46_ip *nexthop) > + struct in6_addr *prefix, unsigned int *plen, > + struct in6_addr *nexthop) > { > if (!ip46_parse_cidr(s_prefix, prefix, plen)) { > return false; > @@ -886,7 +886,7 @@ static bool > add_to_routes_learned(struct hmap *routes_learned, > const struct nbrec_logical_router_static_route *nb_route) > { > - struct v46_ip prefix, nexthop; > + struct in6_addr prefix, nexthop; > unsigned int plen; > if (!parse_route(nb_route->ip_prefix, nb_route->nexthop, > &prefix, &plen, &nexthop)) { > @@ -903,62 +903,60 @@ add_to_routes_learned(struct hmap *routes_learned, > } > > static bool > -get_nexthop_from_lport_addresses(int family, > +get_nexthop_from_lport_addresses(bool is_v4, > const struct lport_addresses *laddr, > - struct v46_ip *nexthop) > + struct in6_addr *nexthop) > { > - memset(nexthop, 0, sizeof *nexthop); > - nexthop->family = family; > - if (family == AF_INET) { > + if (is_v4) { > if (!laddr->n_ipv4_addrs) { > return false; > } > - nexthop->ipv4 = laddr->ipv4_addrs[0].addr; > + in6_addr_set_mapped_ipv4(nexthop, laddr->ipv4_addrs[0].addr); > return true; > } > > /* ipv6 */ > if (laddr->n_ipv6_addrs) { > - nexthop->ipv6 = laddr->ipv6_addrs[0].addr; > + *nexthop = laddr->ipv6_addrs[0].addr; > return true; > } > > /* ipv6 link local */ > - in6_generate_lla(laddr->ea, &nexthop->ipv6); > + in6_generate_lla(laddr->ea, nexthop); > return true; > } > > static bool > -prefix_is_link_local(struct v46_ip *prefix, unsigned int plen) > +prefix_is_link_local(struct in6_addr *prefix, unsigned int plen) > { > - if (prefix->family == AF_INET) { > + if (IN6_IS_ADDR_V4MAPPED(prefix)) { > /* Link local range is "169.254.0.0/16". */ > if (plen < 16) { > return false; > } > ovs_be32 lla; > inet_pton(AF_INET, "169.254.0.0", &lla); > - return ((prefix->ipv4 & htonl(0xffff0000)) == lla); > + return ((in6_addr_get_mapped_ipv4(prefix) & htonl(0xffff0000)) == lla); > } > > /* ipv6, link local range is "fe80::/10". */ > if (plen < 10) { > return false; > } > - return (((prefix->ipv6.s6_addr[0] & 0xff) == 0xfe) && > - ((prefix->ipv6.s6_addr[1] & 0xc0) == 0x80)); > + return (((prefix->s6_addr[0] & 0xff) == 0xfe) && > + ((prefix->s6_addr[1] & 0xc0) == 0x80)); > } > > static bool > prefix_is_black_listed(const struct smap *nb_options, > - struct v46_ip *prefix, > + struct in6_addr *prefix, > unsigned int plen) > { > const char *blacklist = smap_get(nb_options, "ic-route-blacklist"); > if (!blacklist || !blacklist[0]) { > return false; > } > - struct v46_ip bl_prefix; > + struct in6_addr bl_prefix; > unsigned int bl_plen; > char *cur, *next, *start; > next = start = xstrdup(blacklist); > @@ -971,7 +969,7 @@ prefix_is_black_listed(const struct smap *nb_options, > continue; > } > > - if (bl_prefix.family != prefix->family) { > + if (IN6_IS_ADDR_V4MAPPED(&bl_prefix) != IN6_IS_ADDR_V4MAPPED(prefix)) { > continue; > } > > @@ -980,16 +978,19 @@ prefix_is_black_listed(const struct smap *nb_options, > continue; > } > > - if (prefix->family == AF_INET) { > + if (IN6_IS_ADDR_V4MAPPED(prefix)) { > + ovs_be32 bl_prefix_v4 = in6_addr_get_mapped_ipv4(&bl_prefix); > + ovs_be32 prefix_v4 = in6_addr_get_mapped_ipv4(prefix); > ovs_be32 mask = be32_prefix_mask(bl_plen); > - if ((prefix->ipv4 & mask) != (bl_prefix.ipv4 & mask)) { > + > + if ((prefix_v4 & mask) != (bl_prefix_v4 & mask)) { > continue; > } > } else { > struct in6_addr mask = ipv6_create_mask(bl_plen); > for (int i = 0; i < 16 && mask.s6_addr[i] != 0; i++) { > - if ((prefix->ipv6.s6_addr[i] & mask.s6_addr[i]) > - != (bl_prefix.ipv6.s6_addr[i] & mask.s6_addr[i])) { > + if ((prefix->s6_addr[i] & mask.s6_addr[i]) > + != (bl_prefix.s6_addr[i] & mask.s6_addr[i])) { > continue; > } > } > @@ -1003,7 +1004,7 @@ prefix_is_black_listed(const struct smap *nb_options, > > static bool > route_need_advertise(const char *policy, > - struct v46_ip *prefix, > + struct in6_addr *prefix, > unsigned int plen, > const struct smap *nb_options) > { > @@ -1036,7 +1037,7 @@ add_to_routes_ad(struct hmap *routes_ad, > const struct lport_addresses *nexthop_addresses, > const struct smap *nb_options) > { > - struct v46_ip prefix, nexthop; > + struct in6_addr prefix, nexthop; > unsigned int plen; > if (!parse_route(nb_route->ip_prefix, nb_route->nexthop, > &prefix, &plen, &nexthop)) { > @@ -1047,7 +1048,7 @@ add_to_routes_ad(struct hmap *routes_ad, > return; > } > > - if (!get_nexthop_from_lport_addresses(prefix.family, > + if (!get_nexthop_from_lport_addresses(IN6_IS_ADDR_V4MAPPED(&prefix), > nexthop_addresses, > &nexthop)) { > return; > @@ -1068,7 +1069,7 @@ add_network_to_routes_ad(struct hmap *routes_ad, const char *network, > const struct lport_addresses *nexthop_addresses, > const struct smap *nb_options) > { > - struct v46_ip prefix, nexthop; > + struct in6_addr prefix, nexthop; > unsigned int plen; > if (!ip46_parse_cidr(network, &prefix, &plen)) { > return; > @@ -1080,14 +1081,29 @@ add_network_to_routes_ad(struct hmap *routes_ad, const char *network, > return; > } > > - if (!get_nexthop_from_lport_addresses(prefix.family, > + if (!get_nexthop_from_lport_addresses(IN6_IS_ADDR_V4MAPPED(&prefix), > nexthop_addresses, > &nexthop)) { > return; > } > > - VLOG_DBG("Route ad: direct network %s of lrp %s, nexthop "IP_FMT, > - network, nb_lrp->name, IP_ARGS(nexthop.ipv4)); > + if (VLOG_IS_DBG_ENABLED()) { > + struct ds msg = DS_EMPTY_INITIALIZER; > + > + ds_put_format(&msg, "Route ad: direct network %s of lrp %s, nexthop ", > + network, nb_lrp->name); > + > + if (IN6_IS_ADDR_V4MAPPED(&nexthop)) { > + ds_put_format(&msg, IP_FMT, > + IP_ARGS(in6_addr_get_mapped_ipv4(&nexthop))); > + } else { > + ipv6_format_addr(&nexthop, &msg); > + } > + > + VLOG_DBG("%s", ds_cstr(&msg)); > + ds_destroy(&msg); > + } > + > struct ic_route_info *ic_route = xzalloc(sizeof *ic_route); > ic_route->prefix = prefix; > ic_route->plen = plen; > @@ -1098,7 +1114,7 @@ add_network_to_routes_ad(struct hmap *routes_ad, const char *network, > } > > static bool > -route_need_learn(struct v46_ip *prefix, > +route_need_learn(struct in6_addr *prefix, > unsigned int plen, > const struct smap *nb_options) > { > @@ -1133,7 +1149,7 @@ sync_learned_route(struct ic_context *ctx, > if (isb_route->availability_zone == az) { > continue; > } > - struct v46_ip prefix, nexthop; > + struct in6_addr prefix, nexthop; > unsigned int plen; > if (!parse_route(isb_route->ip_prefix, isb_route->nexthop, > &prefix, &plen, &nexthop)) { > @@ -1228,7 +1244,7 @@ advertise_route(struct ic_context *ctx, > continue; > } > > - struct v46_ip prefix, nexthop; > + struct in6_addr prefix, nexthop; > unsigned int plen; > > if (!parse_route(isb_route->ip_prefix, isb_route->nexthop, > @@ -1264,17 +1280,17 @@ advertise_route(struct ic_context *ctx, > icsbrec_route_set_availability_zone(isb_route, az); > > char *prefix_s, *nexthop_s; > - if (route_adv->prefix.family == AF_INET) { > - prefix_s = xasprintf(IP_FMT "/%d", > - IP_ARGS(route_adv->prefix.ipv4), > - route_adv->plen); > - nexthop_s = xasprintf(IP_FMT, IP_ARGS(route_adv->nexthop.ipv4)); > + if (IN6_IS_ADDR_V4MAPPED(&route_adv->prefix)) { > + ovs_be32 ipv4 = in6_addr_get_mapped_ipv4(&route_adv->prefix); > + ovs_be32 nh = in6_addr_get_mapped_ipv4(&route_adv->nexthop); > + prefix_s = xasprintf(IP_FMT "/%d", IP_ARGS(ipv4), route_adv->plen); > + nexthop_s = xasprintf(IP_FMT, IP_ARGS(nh)); > } else { > char network_s[INET6_ADDRSTRLEN]; > - inet_ntop(AF_INET6, &route_adv->prefix.ipv6, network_s, > + inet_ntop(AF_INET6, &route_adv->prefix, network_s, > INET6_ADDRSTRLEN); > prefix_s = xasprintf("%s/%d", network_s, route_adv->plen); > - inet_ntop(AF_INET6, &route_adv->nexthop.ipv6, network_s, > + inet_ntop(AF_INET6, &route_adv->nexthop, network_s, > INET6_ADDRSTRLEN); > nexthop_s = xstrdup(network_s); > } > diff --git a/lib/ovn-util.c b/lib/ovn-util.c > index 1daf665..9ed9991 100644 > --- a/lib/ovn-util.c > +++ b/lib/ovn-util.c > @@ -568,33 +568,24 @@ ovn_chassis_redirect_name(const char *port_name) > } > > bool > -ip46_parse_cidr(const char *str, struct v46_ip *prefix, unsigned int *plen) > +ip46_parse_cidr(const char *str, struct in6_addr *prefix, unsigned int *plen) > { > - memset(prefix, 0, sizeof *prefix); > + ovs_be32 ipv4; > + char *error = ip_parse_cidr(str, &ipv4, plen); > > - char *error = ip_parse_cidr(str, &prefix->ipv4, plen); > if (!error) { > - prefix->family = AF_INET; > + in6_addr_set_mapped_ipv4(prefix, ipv4); > return true; > } > free(error); > - error = ipv6_parse_cidr(str, &prefix->ipv6, plen); > + error = ipv6_parse_cidr(str, prefix, plen); > if (!error) { > - prefix->family = AF_INET6; > return true; > } > free(error); > return false; > } > > -bool > -ip46_equals(const struct v46_ip *addr1, const struct v46_ip *addr2) > -{ > - return (addr1->family == addr2->family && > - (addr1->family == AF_INET ? addr1->ipv4 == addr2->ipv4 : > - IN6_ARE_ADDR_EQUAL(&addr1->ipv6, &addr2->ipv6))); > -} > - > /* The caller must free the returned string. */ > char * > normalize_ipv4_prefix(ovs_be32 ipv4, unsigned int plen) > @@ -609,12 +600,12 @@ normalize_ipv4_prefix(ovs_be32 ipv4, unsigned int plen) > > /* The caller must free the returned string. */ > char * > -normalize_ipv6_prefix(struct in6_addr ipv6, unsigned int plen) > +normalize_ipv6_prefix(const struct in6_addr *ipv6, unsigned int plen) > { > char network_s[INET6_ADDRSTRLEN]; > > struct in6_addr mask = ipv6_create_mask(plen); > - struct in6_addr network = ipv6_addr_bitand(&ipv6, &mask); > + struct in6_addr network = ipv6_addr_bitand(ipv6, &mask); > > inet_ntop(AF_INET6, &network, network_s, INET6_ADDRSTRLEN); > if (plen == 128) { > @@ -625,12 +616,12 @@ normalize_ipv6_prefix(struct in6_addr ipv6, unsigned int plen) > } > > char * > -normalize_v46_prefix(const struct v46_ip *prefix, unsigned int plen) > +normalize_v46_prefix(const struct in6_addr *prefix, unsigned int plen) > { > - if (prefix->family == AF_INET) { > - return normalize_ipv4_prefix(prefix->ipv4, plen); > + if (IN6_IS_ADDR_V4MAPPED(prefix)) { > + return normalize_ipv4_prefix(in6_addr_get_mapped_ipv4(prefix), plen); > } else { > - return normalize_ipv6_prefix(prefix->ipv6, plen); > + return normalize_ipv6_prefix(prefix, plen); > } > } > > diff --git a/lib/ovn-util.h b/lib/ovn-util.h > index 1d22a69..8aef48a 100644 > --- a/lib/ovn-util.h > +++ b/lib/ovn-util.h > @@ -137,21 +137,12 @@ get_sb_port_group_name(const char *nb_pg_name, int64_t dp_tunnel_key, > char *ovn_chassis_redirect_name(const char *port_name); > void ovn_set_pidfile(const char *name); > > -/* An IPv4 or IPv6 address */ > -struct v46_ip { > - int family; > - union { > - ovs_be32 ipv4; > - struct in6_addr ipv6; > - }; > -}; > -bool ip46_parse_cidr(const char *str, struct v46_ip *prefix, > +bool ip46_parse_cidr(const char *str, struct in6_addr *prefix, > unsigned int *plen); > -bool ip46_equals(const struct v46_ip *addr1, const struct v46_ip *addr2); > > char *normalize_ipv4_prefix(ovs_be32 ipv4, unsigned int plen); > -char *normalize_ipv6_prefix(struct in6_addr ipv6, unsigned int plen); > -char *normalize_v46_prefix(const struct v46_ip *prefix, unsigned int plen); > +char *normalize_ipv6_prefix(const struct in6_addr *ipv6, unsigned int plen); > +char *normalize_v46_prefix(const struct in6_addr *prefix, unsigned int plen); > > /* Temporary util function until ovs library has smap_get_unit. */ > unsigned int ovn_smap_get_uint(const struct smap *smap, const char *key, > diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c > index 1ca037f..c2447fd 100644 > --- a/northd/ovn-northd.c > +++ b/northd/ovn-northd.c > @@ -7651,7 +7651,7 @@ build_routing_policy_flow(struct hmap *lflows, struct ovn_datapath *od, > > struct parsed_route { > struct ovs_list list_node; > - struct v46_ip prefix; > + struct in6_addr prefix; > unsigned int plen; > bool is_src_route; > uint32_t hash; > @@ -7673,7 +7673,7 @@ parsed_routes_add(struct ovs_list *routes, > const struct nbrec_logical_router_static_route *route) > { > /* Verify that the next hop is an IP address with an all-ones mask. */ > - struct v46_ip nexthop; > + struct in6_addr nexthop; > unsigned int plen; > if (!ip46_parse_cidr(route->nexthop, &nexthop, &plen)) { > static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); > @@ -7682,8 +7682,8 @@ parsed_routes_add(struct ovs_list *routes, > UUID_ARGS(&route->header_.uuid)); > return NULL; > } > - if ((nexthop.family == AF_INET && plen != 32) || > - (nexthop.family == AF_INET6 && plen != 128)) { > + if ((IN6_IS_ADDR_V4MAPPED(&nexthop) && plen != 32) || > + (!IN6_IS_ADDR_V4MAPPED(&nexthop) && plen != 128)) { > static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); > VLOG_WARN_RL(&rl, "bad next hop mask %s in static route" > UUID_FMT, route->nexthop, > @@ -7692,7 +7692,7 @@ parsed_routes_add(struct ovs_list *routes, > } > > /* Parse ip_prefix */ > - struct v46_ip prefix; > + struct in6_addr prefix; > if (!ip46_parse_cidr(route->ip_prefix, &prefix, &plen)) { > static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); > VLOG_WARN_RL(&rl, "bad 'ip_prefix' %s in static route" > @@ -7702,7 +7702,7 @@ parsed_routes_add(struct ovs_list *routes, > } > > /* Verify that ip_prefix and nexthop have same address familiy. */ > - if (prefix.family != nexthop.family) { > + if (IN6_IS_ADDR_V4MAPPED(&prefix) != IN6_IS_ADDR_V4MAPPED(&nexthop)) { > static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); > VLOG_WARN_RL(&rl, "Address family doesn't match between 'ip_prefix' %s" > " and 'nexthop' %s in static route"UUID_FMT, > @@ -7743,7 +7743,7 @@ struct ecmp_route_list_node { > struct ecmp_groups_node { > struct hmap_node hmap_node; /* In ecmp_groups */ > uint16_t id; /* starts from 1 */ > - struct v46_ip prefix; > + struct in6_addr prefix; > unsigned int plen; > bool is_src_route; > uint16_t route_count; > @@ -7794,7 +7794,7 @@ ecmp_groups_find(struct hmap *ecmp_groups, struct parsed_route *route) > { > struct ecmp_groups_node *eg; > HMAP_FOR_EACH_WITH_HASH (eg, hmap_node, route->hash, ecmp_groups) { > - if (ip46_equals(&eg->prefix, &route->prefix) && > + if (ipv6_addr_equals(&eg->prefix, &route->prefix) && > eg->plen == route->plen && > eg->is_src_route == route->is_src_route) { > return eg; > @@ -7841,7 +7841,7 @@ unique_routes_remove(struct hmap *unique_routes, > { > struct unique_routes_node *ur; > HMAP_FOR_EACH_WITH_HASH (ur, hmap_node, route->hash, unique_routes) { > - if (ip46_equals(&route->prefix, &ur->route->prefix) && > + if (ipv6_addr_equals(&route->prefix, &ur->route->prefix) && > route->plen == ur->route->plen && > route->is_src_route == ur->route->is_src_route) { > hmap_remove(unique_routes, &ur->hmap_node); > @@ -7865,15 +7865,15 @@ unique_routes_destroy(struct hmap *unique_routes) > } > > static char * > -build_route_prefix_s(const struct v46_ip *prefix, unsigned int plen) > +build_route_prefix_s(const struct in6_addr *prefix, unsigned int plen) > { > char *prefix_s; > - if (prefix->family == AF_INET) { > - prefix_s = xasprintf(IP_FMT, IP_ARGS(prefix->ipv4 & > + if (IN6_IS_ADDR_V4MAPPED(prefix)) { > + prefix_s = xasprintf(IP_FMT, IP_ARGS(in6_addr_get_mapped_ipv4(prefix) & > be32_prefix_mask(plen))); > } else { > struct in6_addr mask = ipv6_create_mask(plen); > - struct in6_addr network = ipv6_addr_bitand(&prefix->ipv6, &mask); > + struct in6_addr network = ipv6_addr_bitand(prefix, &mask); > prefix_s = xmalloc(INET6_ADDRSTRLEN); > inet_ntop(AF_INET6, &network, prefix_s, INET6_ADDRSTRLEN); > } > @@ -7987,7 +7987,7 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows, > */ > ds_put_format(&match, "inport == %s && ip%s.%s == %s", > out_port->json_key, > - route->prefix.family == AF_INET ? "4" : "6", > + IN6_IS_ADDR_V4MAPPED(&route->prefix) ? "4" : "6", > route->is_src_route ? "dst" : "src", > cidr); > ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_DEFRAG, 100, > @@ -8026,7 +8026,7 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows, > ds_put_format(&actions, "ip.ttl--; flags.loopback = 1; " > "eth.src = %s; %sreg1 = %s; outport = %s; next;", > out_port->lrp_networks.ea_s, > - route->prefix.family == AF_INET ? "" : "xx", > + IN6_IS_ADDR_V4MAPPED(&route->prefix) ? "" : "xx", > port_ip, out_port->json_key); > ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_IP_ROUTING, 100, > ds_cstr(&match), ds_cstr(&actions), > @@ -8048,7 +8048,7 @@ build_ecmp_route_flow(struct hmap *lflows, struct ovn_datapath *od, > struct hmap *ports, struct ecmp_groups_node *eg) > > { > - bool is_ipv4 = (eg->prefix.family == AF_INET); > + bool is_ipv4 = IN6_IS_ADDR_V4MAPPED(&eg->prefix); > uint16_t priority; > struct ecmp_route_list_node *er; > struct ds route_match = DS_EMPTY_INITIALIZER; > @@ -8182,13 +8182,13 @@ build_static_route_flow(struct hmap *lflows, struct ovn_datapath *od, > { > const char *lrp_addr_s = NULL; > struct ovn_port *out_port = NULL; > - bool is_ipv4 = (route_->prefix.family == AF_INET); > > const struct nbrec_logical_router_static_route *route = route_->route; > > /* Find the outgoing port. */ > - if (!find_static_route_outport(od, ports, route, is_ipv4, &lrp_addr_s, > - &out_port)) { > + if (!find_static_route_outport(od, ports, route, > + IN6_IS_ADDR_V4MAPPED(&route_->prefix), > + &lrp_addr_s, &out_port)) { > return; > } > > diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c > index abc674f..aad6a36 100644 > --- a/utilities/ovn-nbctl.c > +++ b/utilities/ovn-nbctl.c > @@ -3559,7 +3559,7 @@ normalize_ipv6_prefix_str(const char *orig_prefix) > free(error); > return NULL; > } > - return normalize_ipv6_prefix(ipv6, plen); > + return normalize_ipv6_prefix(&ipv6, plen); > } > > /* The caller must free the returned string. */ > @@ -3596,7 +3596,7 @@ normalize_ipv6_addr_str(const char *orig_addr) > return NULL; > } > > - return normalize_ipv6_prefix(ipv6, 128); > + return normalize_ipv6_prefix(&ipv6, 128); > } > > /* Similar to normalize_prefix_str but must be an un-masked address. > -- > 1.8.3.1 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev >
diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c index 923969f..ba28bc9 100644 --- a/ic/ovn-ic.c +++ b/ic/ovn-ic.c @@ -817,9 +817,9 @@ struct ic_router_info { /* Represents an interconnection route entry. */ struct ic_route_info { struct hmap_node node; - struct v46_ip prefix; + struct in6_addr prefix; unsigned int plen; - struct v46_ip nexthop; + struct in6_addr nexthop; /* Either nb_route or nb_lrp is set and the other one must be NULL. * - For a route that is learned from IC-SB, or a static route that is @@ -832,23 +832,23 @@ struct ic_route_info { }; static uint32_t -ic_route_hash(const struct v46_ip *prefix, unsigned int plen, - const struct v46_ip *nexthop) +ic_route_hash(const struct in6_addr *prefix, unsigned int plen, + const struct in6_addr *nexthop) { uint32_t basis = hash_bytes(prefix, sizeof *prefix, (uint32_t)plen); return hash_bytes(nexthop, sizeof *nexthop, basis); } static struct ic_route_info * -ic_route_find(struct hmap *routes, const struct v46_ip *prefix, - unsigned int plen, const struct v46_ip *nexthop) +ic_route_find(struct hmap *routes, const struct in6_addr *prefix, + unsigned int plen, const struct in6_addr *nexthop) { struct ic_route_info *r; uint32_t hash = ic_route_hash(prefix, plen, nexthop); HMAP_FOR_EACH_WITH_HASH (r, node, hash, routes) { - if (ip46_equals(&r->prefix, prefix) && + if (ipv6_addr_equals(&r->prefix, prefix) && r->plen == plen && - ip46_equals(&r->nexthop, nexthop)) { + ipv6_addr_equals(&r->nexthop, nexthop)) { return r; } } @@ -870,8 +870,8 @@ ic_router_find(struct hmap *ic_lrs, const struct nbrec_logical_router *lr) static bool parse_route(const char *s_prefix, const char *s_nexthop, - struct v46_ip *prefix, unsigned int *plen, - struct v46_ip *nexthop) + struct in6_addr *prefix, unsigned int *plen, + struct in6_addr *nexthop) { if (!ip46_parse_cidr(s_prefix, prefix, plen)) { return false; @@ -886,7 +886,7 @@ static bool add_to_routes_learned(struct hmap *routes_learned, const struct nbrec_logical_router_static_route *nb_route) { - struct v46_ip prefix, nexthop; + struct in6_addr prefix, nexthop; unsigned int plen; if (!parse_route(nb_route->ip_prefix, nb_route->nexthop, &prefix, &plen, &nexthop)) { @@ -903,62 +903,60 @@ add_to_routes_learned(struct hmap *routes_learned, } static bool -get_nexthop_from_lport_addresses(int family, +get_nexthop_from_lport_addresses(bool is_v4, const struct lport_addresses *laddr, - struct v46_ip *nexthop) + struct in6_addr *nexthop) { - memset(nexthop, 0, sizeof *nexthop); - nexthop->family = family; - if (family == AF_INET) { + if (is_v4) { if (!laddr->n_ipv4_addrs) { return false; } - nexthop->ipv4 = laddr->ipv4_addrs[0].addr; + in6_addr_set_mapped_ipv4(nexthop, laddr->ipv4_addrs[0].addr); return true; } /* ipv6 */ if (laddr->n_ipv6_addrs) { - nexthop->ipv6 = laddr->ipv6_addrs[0].addr; + *nexthop = laddr->ipv6_addrs[0].addr; return true; } /* ipv6 link local */ - in6_generate_lla(laddr->ea, &nexthop->ipv6); + in6_generate_lla(laddr->ea, nexthop); return true; } static bool -prefix_is_link_local(struct v46_ip *prefix, unsigned int plen) +prefix_is_link_local(struct in6_addr *prefix, unsigned int plen) { - if (prefix->family == AF_INET) { + if (IN6_IS_ADDR_V4MAPPED(prefix)) { /* Link local range is "169.254.0.0/16". */ if (plen < 16) { return false; } ovs_be32 lla; inet_pton(AF_INET, "169.254.0.0", &lla); - return ((prefix->ipv4 & htonl(0xffff0000)) == lla); + return ((in6_addr_get_mapped_ipv4(prefix) & htonl(0xffff0000)) == lla); } /* ipv6, link local range is "fe80::/10". */ if (plen < 10) { return false; } - return (((prefix->ipv6.s6_addr[0] & 0xff) == 0xfe) && - ((prefix->ipv6.s6_addr[1] & 0xc0) == 0x80)); + return (((prefix->s6_addr[0] & 0xff) == 0xfe) && + ((prefix->s6_addr[1] & 0xc0) == 0x80)); } static bool prefix_is_black_listed(const struct smap *nb_options, - struct v46_ip *prefix, + struct in6_addr *prefix, unsigned int plen) { const char *blacklist = smap_get(nb_options, "ic-route-blacklist"); if (!blacklist || !blacklist[0]) { return false; } - struct v46_ip bl_prefix; + struct in6_addr bl_prefix; unsigned int bl_plen; char *cur, *next, *start; next = start = xstrdup(blacklist); @@ -971,7 +969,7 @@ prefix_is_black_listed(const struct smap *nb_options, continue; } - if (bl_prefix.family != prefix->family) { + if (IN6_IS_ADDR_V4MAPPED(&bl_prefix) != IN6_IS_ADDR_V4MAPPED(prefix)) { continue; } @@ -980,16 +978,19 @@ prefix_is_black_listed(const struct smap *nb_options, continue; } - if (prefix->family == AF_INET) { + if (IN6_IS_ADDR_V4MAPPED(prefix)) { + ovs_be32 bl_prefix_v4 = in6_addr_get_mapped_ipv4(&bl_prefix); + ovs_be32 prefix_v4 = in6_addr_get_mapped_ipv4(prefix); ovs_be32 mask = be32_prefix_mask(bl_plen); - if ((prefix->ipv4 & mask) != (bl_prefix.ipv4 & mask)) { + + if ((prefix_v4 & mask) != (bl_prefix_v4 & mask)) { continue; } } else { struct in6_addr mask = ipv6_create_mask(bl_plen); for (int i = 0; i < 16 && mask.s6_addr[i] != 0; i++) { - if ((prefix->ipv6.s6_addr[i] & mask.s6_addr[i]) - != (bl_prefix.ipv6.s6_addr[i] & mask.s6_addr[i])) { + if ((prefix->s6_addr[i] & mask.s6_addr[i]) + != (bl_prefix.s6_addr[i] & mask.s6_addr[i])) { continue; } } @@ -1003,7 +1004,7 @@ prefix_is_black_listed(const struct smap *nb_options, static bool route_need_advertise(const char *policy, - struct v46_ip *prefix, + struct in6_addr *prefix, unsigned int plen, const struct smap *nb_options) { @@ -1036,7 +1037,7 @@ add_to_routes_ad(struct hmap *routes_ad, const struct lport_addresses *nexthop_addresses, const struct smap *nb_options) { - struct v46_ip prefix, nexthop; + struct in6_addr prefix, nexthop; unsigned int plen; if (!parse_route(nb_route->ip_prefix, nb_route->nexthop, &prefix, &plen, &nexthop)) { @@ -1047,7 +1048,7 @@ add_to_routes_ad(struct hmap *routes_ad, return; } - if (!get_nexthop_from_lport_addresses(prefix.family, + if (!get_nexthop_from_lport_addresses(IN6_IS_ADDR_V4MAPPED(&prefix), nexthop_addresses, &nexthop)) { return; @@ -1068,7 +1069,7 @@ add_network_to_routes_ad(struct hmap *routes_ad, const char *network, const struct lport_addresses *nexthop_addresses, const struct smap *nb_options) { - struct v46_ip prefix, nexthop; + struct in6_addr prefix, nexthop; unsigned int plen; if (!ip46_parse_cidr(network, &prefix, &plen)) { return; @@ -1080,14 +1081,29 @@ add_network_to_routes_ad(struct hmap *routes_ad, const char *network, return; } - if (!get_nexthop_from_lport_addresses(prefix.family, + if (!get_nexthop_from_lport_addresses(IN6_IS_ADDR_V4MAPPED(&prefix), nexthop_addresses, &nexthop)) { return; } - VLOG_DBG("Route ad: direct network %s of lrp %s, nexthop "IP_FMT, - network, nb_lrp->name, IP_ARGS(nexthop.ipv4)); + if (VLOG_IS_DBG_ENABLED()) { + struct ds msg = DS_EMPTY_INITIALIZER; + + ds_put_format(&msg, "Route ad: direct network %s of lrp %s, nexthop ", + network, nb_lrp->name); + + if (IN6_IS_ADDR_V4MAPPED(&nexthop)) { + ds_put_format(&msg, IP_FMT, + IP_ARGS(in6_addr_get_mapped_ipv4(&nexthop))); + } else { + ipv6_format_addr(&nexthop, &msg); + } + + VLOG_DBG("%s", ds_cstr(&msg)); + ds_destroy(&msg); + } + struct ic_route_info *ic_route = xzalloc(sizeof *ic_route); ic_route->prefix = prefix; ic_route->plen = plen; @@ -1098,7 +1114,7 @@ add_network_to_routes_ad(struct hmap *routes_ad, const char *network, } static bool -route_need_learn(struct v46_ip *prefix, +route_need_learn(struct in6_addr *prefix, unsigned int plen, const struct smap *nb_options) { @@ -1133,7 +1149,7 @@ sync_learned_route(struct ic_context *ctx, if (isb_route->availability_zone == az) { continue; } - struct v46_ip prefix, nexthop; + struct in6_addr prefix, nexthop; unsigned int plen; if (!parse_route(isb_route->ip_prefix, isb_route->nexthop, &prefix, &plen, &nexthop)) { @@ -1228,7 +1244,7 @@ advertise_route(struct ic_context *ctx, continue; } - struct v46_ip prefix, nexthop; + struct in6_addr prefix, nexthop; unsigned int plen; if (!parse_route(isb_route->ip_prefix, isb_route->nexthop, @@ -1264,17 +1280,17 @@ advertise_route(struct ic_context *ctx, icsbrec_route_set_availability_zone(isb_route, az); char *prefix_s, *nexthop_s; - if (route_adv->prefix.family == AF_INET) { - prefix_s = xasprintf(IP_FMT "/%d", - IP_ARGS(route_adv->prefix.ipv4), - route_adv->plen); - nexthop_s = xasprintf(IP_FMT, IP_ARGS(route_adv->nexthop.ipv4)); + if (IN6_IS_ADDR_V4MAPPED(&route_adv->prefix)) { + ovs_be32 ipv4 = in6_addr_get_mapped_ipv4(&route_adv->prefix); + ovs_be32 nh = in6_addr_get_mapped_ipv4(&route_adv->nexthop); + prefix_s = xasprintf(IP_FMT "/%d", IP_ARGS(ipv4), route_adv->plen); + nexthop_s = xasprintf(IP_FMT, IP_ARGS(nh)); } else { char network_s[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &route_adv->prefix.ipv6, network_s, + inet_ntop(AF_INET6, &route_adv->prefix, network_s, INET6_ADDRSTRLEN); prefix_s = xasprintf("%s/%d", network_s, route_adv->plen); - inet_ntop(AF_INET6, &route_adv->nexthop.ipv6, network_s, + inet_ntop(AF_INET6, &route_adv->nexthop, network_s, INET6_ADDRSTRLEN); nexthop_s = xstrdup(network_s); } diff --git a/lib/ovn-util.c b/lib/ovn-util.c index 1daf665..9ed9991 100644 --- a/lib/ovn-util.c +++ b/lib/ovn-util.c @@ -568,33 +568,24 @@ ovn_chassis_redirect_name(const char *port_name) } bool -ip46_parse_cidr(const char *str, struct v46_ip *prefix, unsigned int *plen) +ip46_parse_cidr(const char *str, struct in6_addr *prefix, unsigned int *plen) { - memset(prefix, 0, sizeof *prefix); + ovs_be32 ipv4; + char *error = ip_parse_cidr(str, &ipv4, plen); - char *error = ip_parse_cidr(str, &prefix->ipv4, plen); if (!error) { - prefix->family = AF_INET; + in6_addr_set_mapped_ipv4(prefix, ipv4); return true; } free(error); - error = ipv6_parse_cidr(str, &prefix->ipv6, plen); + error = ipv6_parse_cidr(str, prefix, plen); if (!error) { - prefix->family = AF_INET6; return true; } free(error); return false; } -bool -ip46_equals(const struct v46_ip *addr1, const struct v46_ip *addr2) -{ - return (addr1->family == addr2->family && - (addr1->family == AF_INET ? addr1->ipv4 == addr2->ipv4 : - IN6_ARE_ADDR_EQUAL(&addr1->ipv6, &addr2->ipv6))); -} - /* The caller must free the returned string. */ char * normalize_ipv4_prefix(ovs_be32 ipv4, unsigned int plen) @@ -609,12 +600,12 @@ normalize_ipv4_prefix(ovs_be32 ipv4, unsigned int plen) /* The caller must free the returned string. */ char * -normalize_ipv6_prefix(struct in6_addr ipv6, unsigned int plen) +normalize_ipv6_prefix(const struct in6_addr *ipv6, unsigned int plen) { char network_s[INET6_ADDRSTRLEN]; struct in6_addr mask = ipv6_create_mask(plen); - struct in6_addr network = ipv6_addr_bitand(&ipv6, &mask); + struct in6_addr network = ipv6_addr_bitand(ipv6, &mask); inet_ntop(AF_INET6, &network, network_s, INET6_ADDRSTRLEN); if (plen == 128) { @@ -625,12 +616,12 @@ normalize_ipv6_prefix(struct in6_addr ipv6, unsigned int plen) } char * -normalize_v46_prefix(const struct v46_ip *prefix, unsigned int plen) +normalize_v46_prefix(const struct in6_addr *prefix, unsigned int plen) { - if (prefix->family == AF_INET) { - return normalize_ipv4_prefix(prefix->ipv4, plen); + if (IN6_IS_ADDR_V4MAPPED(prefix)) { + return normalize_ipv4_prefix(in6_addr_get_mapped_ipv4(prefix), plen); } else { - return normalize_ipv6_prefix(prefix->ipv6, plen); + return normalize_ipv6_prefix(prefix, plen); } } diff --git a/lib/ovn-util.h b/lib/ovn-util.h index 1d22a69..8aef48a 100644 --- a/lib/ovn-util.h +++ b/lib/ovn-util.h @@ -137,21 +137,12 @@ get_sb_port_group_name(const char *nb_pg_name, int64_t dp_tunnel_key, char *ovn_chassis_redirect_name(const char *port_name); void ovn_set_pidfile(const char *name); -/* An IPv4 or IPv6 address */ -struct v46_ip { - int family; - union { - ovs_be32 ipv4; - struct in6_addr ipv6; - }; -}; -bool ip46_parse_cidr(const char *str, struct v46_ip *prefix, +bool ip46_parse_cidr(const char *str, struct in6_addr *prefix, unsigned int *plen); -bool ip46_equals(const struct v46_ip *addr1, const struct v46_ip *addr2); char *normalize_ipv4_prefix(ovs_be32 ipv4, unsigned int plen); -char *normalize_ipv6_prefix(struct in6_addr ipv6, unsigned int plen); -char *normalize_v46_prefix(const struct v46_ip *prefix, unsigned int plen); +char *normalize_ipv6_prefix(const struct in6_addr *ipv6, unsigned int plen); +char *normalize_v46_prefix(const struct in6_addr *prefix, unsigned int plen); /* Temporary util function until ovs library has smap_get_unit. */ unsigned int ovn_smap_get_uint(const struct smap *smap, const char *key, diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 1ca037f..c2447fd 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -7651,7 +7651,7 @@ build_routing_policy_flow(struct hmap *lflows, struct ovn_datapath *od, struct parsed_route { struct ovs_list list_node; - struct v46_ip prefix; + struct in6_addr prefix; unsigned int plen; bool is_src_route; uint32_t hash; @@ -7673,7 +7673,7 @@ parsed_routes_add(struct ovs_list *routes, const struct nbrec_logical_router_static_route *route) { /* Verify that the next hop is an IP address with an all-ones mask. */ - struct v46_ip nexthop; + struct in6_addr nexthop; unsigned int plen; if (!ip46_parse_cidr(route->nexthop, &nexthop, &plen)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); @@ -7682,8 +7682,8 @@ parsed_routes_add(struct ovs_list *routes, UUID_ARGS(&route->header_.uuid)); return NULL; } - if ((nexthop.family == AF_INET && plen != 32) || - (nexthop.family == AF_INET6 && plen != 128)) { + if ((IN6_IS_ADDR_V4MAPPED(&nexthop) && plen != 32) || + (!IN6_IS_ADDR_V4MAPPED(&nexthop) && plen != 128)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); VLOG_WARN_RL(&rl, "bad next hop mask %s in static route" UUID_FMT, route->nexthop, @@ -7692,7 +7692,7 @@ parsed_routes_add(struct ovs_list *routes, } /* Parse ip_prefix */ - struct v46_ip prefix; + struct in6_addr prefix; if (!ip46_parse_cidr(route->ip_prefix, &prefix, &plen)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); VLOG_WARN_RL(&rl, "bad 'ip_prefix' %s in static route" @@ -7702,7 +7702,7 @@ parsed_routes_add(struct ovs_list *routes, } /* Verify that ip_prefix and nexthop have same address familiy. */ - if (prefix.family != nexthop.family) { + if (IN6_IS_ADDR_V4MAPPED(&prefix) != IN6_IS_ADDR_V4MAPPED(&nexthop)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); VLOG_WARN_RL(&rl, "Address family doesn't match between 'ip_prefix' %s" " and 'nexthop' %s in static route"UUID_FMT, @@ -7743,7 +7743,7 @@ struct ecmp_route_list_node { struct ecmp_groups_node { struct hmap_node hmap_node; /* In ecmp_groups */ uint16_t id; /* starts from 1 */ - struct v46_ip prefix; + struct in6_addr prefix; unsigned int plen; bool is_src_route; uint16_t route_count; @@ -7794,7 +7794,7 @@ ecmp_groups_find(struct hmap *ecmp_groups, struct parsed_route *route) { struct ecmp_groups_node *eg; HMAP_FOR_EACH_WITH_HASH (eg, hmap_node, route->hash, ecmp_groups) { - if (ip46_equals(&eg->prefix, &route->prefix) && + if (ipv6_addr_equals(&eg->prefix, &route->prefix) && eg->plen == route->plen && eg->is_src_route == route->is_src_route) { return eg; @@ -7841,7 +7841,7 @@ unique_routes_remove(struct hmap *unique_routes, { struct unique_routes_node *ur; HMAP_FOR_EACH_WITH_HASH (ur, hmap_node, route->hash, unique_routes) { - if (ip46_equals(&route->prefix, &ur->route->prefix) && + if (ipv6_addr_equals(&route->prefix, &ur->route->prefix) && route->plen == ur->route->plen && route->is_src_route == ur->route->is_src_route) { hmap_remove(unique_routes, &ur->hmap_node); @@ -7865,15 +7865,15 @@ unique_routes_destroy(struct hmap *unique_routes) } static char * -build_route_prefix_s(const struct v46_ip *prefix, unsigned int plen) +build_route_prefix_s(const struct in6_addr *prefix, unsigned int plen) { char *prefix_s; - if (prefix->family == AF_INET) { - prefix_s = xasprintf(IP_FMT, IP_ARGS(prefix->ipv4 & + if (IN6_IS_ADDR_V4MAPPED(prefix)) { + prefix_s = xasprintf(IP_FMT, IP_ARGS(in6_addr_get_mapped_ipv4(prefix) & be32_prefix_mask(plen))); } else { struct in6_addr mask = ipv6_create_mask(plen); - struct in6_addr network = ipv6_addr_bitand(&prefix->ipv6, &mask); + struct in6_addr network = ipv6_addr_bitand(prefix, &mask); prefix_s = xmalloc(INET6_ADDRSTRLEN); inet_ntop(AF_INET6, &network, prefix_s, INET6_ADDRSTRLEN); } @@ -7987,7 +7987,7 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows, */ ds_put_format(&match, "inport == %s && ip%s.%s == %s", out_port->json_key, - route->prefix.family == AF_INET ? "4" : "6", + IN6_IS_ADDR_V4MAPPED(&route->prefix) ? "4" : "6", route->is_src_route ? "dst" : "src", cidr); ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_DEFRAG, 100, @@ -8026,7 +8026,7 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows, ds_put_format(&actions, "ip.ttl--; flags.loopback = 1; " "eth.src = %s; %sreg1 = %s; outport = %s; next;", out_port->lrp_networks.ea_s, - route->prefix.family == AF_INET ? "" : "xx", + IN6_IS_ADDR_V4MAPPED(&route->prefix) ? "" : "xx", port_ip, out_port->json_key); ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_IP_ROUTING, 100, ds_cstr(&match), ds_cstr(&actions), @@ -8048,7 +8048,7 @@ build_ecmp_route_flow(struct hmap *lflows, struct ovn_datapath *od, struct hmap *ports, struct ecmp_groups_node *eg) { - bool is_ipv4 = (eg->prefix.family == AF_INET); + bool is_ipv4 = IN6_IS_ADDR_V4MAPPED(&eg->prefix); uint16_t priority; struct ecmp_route_list_node *er; struct ds route_match = DS_EMPTY_INITIALIZER; @@ -8182,13 +8182,13 @@ build_static_route_flow(struct hmap *lflows, struct ovn_datapath *od, { const char *lrp_addr_s = NULL; struct ovn_port *out_port = NULL; - bool is_ipv4 = (route_->prefix.family == AF_INET); const struct nbrec_logical_router_static_route *route = route_->route; /* Find the outgoing port. */ - if (!find_static_route_outport(od, ports, route, is_ipv4, &lrp_addr_s, - &out_port)) { + if (!find_static_route_outport(od, ports, route, + IN6_IS_ADDR_V4MAPPED(&route_->prefix), + &lrp_addr_s, &out_port)) { return; } diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c index abc674f..aad6a36 100644 --- a/utilities/ovn-nbctl.c +++ b/utilities/ovn-nbctl.c @@ -3559,7 +3559,7 @@ normalize_ipv6_prefix_str(const char *orig_prefix) free(error); return NULL; } - return normalize_ipv6_prefix(ipv6, plen); + return normalize_ipv6_prefix(&ipv6, plen); } /* The caller must free the returned string. */ @@ -3596,7 +3596,7 @@ normalize_ipv6_addr_str(const char *orig_addr) return NULL; } - return normalize_ipv6_prefix(ipv6, 128); + return normalize_ipv6_prefix(&ipv6, 128); } /* Similar to normalize_prefix_str but must be an un-masked address.
Use struct in6_addr instead and IPv4-mapped IPs. Reported-at: https://mail.openvswitch.org/pipermail/ovs-dev/2020-October/376160.html Fixes: 719f586e4d38 ("northd: Add lflows for IPv6 NAT.") Suggested-by: Ilya Maximets <i.maximets@ovn.org> Signed-off-by: Dumitru Ceara <dceara@redhat.com> --- ic/ovn-ic.c | 112 ++++++++++++++++++++++++++++---------------------- lib/ovn-util.c | 31 +++++--------- lib/ovn-util.h | 15 ++----- northd/ovn-northd.c | 38 ++++++++--------- utilities/ovn-nbctl.c | 4 +- 5 files changed, 99 insertions(+), 101 deletions(-)