Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/810804/?format=api
{ "id": 810804, "url": "http://patchwork.ozlabs.org/api/patches/810804/?format=api", "web_url": "http://patchwork.ozlabs.org/project/openvswitch/patch/20170906210839.26091-4-mmichels@redhat.com/", "project": { "id": 47, "url": "http://patchwork.ozlabs.org/api/projects/47/?format=api", "name": "Open vSwitch", "link_name": "openvswitch", "list_id": "ovs-dev.openvswitch.org", "list_email": "ovs-dev@openvswitch.org", "web_url": "http://openvswitch.org/", "scm_url": "git@github.com:openvswitch/ovs.git", "webscm_url": "https://github.com/openvswitch/ovs", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20170906210839.26091-4-mmichels@redhat.com>", "list_archive_url": null, "date": "2017-09-06T21:08:38", "name": "[ovs-dev,3/4] ovn: Allow northd to install IPv6 ct_lb logical flows.", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "eb8835b6eb42996feb163248ab19fd2cea50db40", "submitter": { "id": 71978, "url": "http://patchwork.ozlabs.org/api/people/71978/?format=api", "name": "Mark Michelson", "email": "mmichels@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/openvswitch/patch/20170906210839.26091-4-mmichels@redhat.com/mbox/", "series": [ { "id": 1883, "url": "http://patchwork.ozlabs.org/api/series/1883/?format=api", "web_url": "http://patchwork.ozlabs.org/project/openvswitch/list/?series=1883", "date": "2017-09-06T21:08:35", "name": "ovn: Add support for IPv6 load balancers", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/1883/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/810804/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/810804/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<ovs-dev-bounces@openvswitch.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "dev@openvswitch.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "ovs-dev@mail.linuxfoundation.org" ], "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=openvswitch.org\n\t(client-ip=140.211.169.12; helo=mail.linuxfoundation.org;\n\tenvelope-from=ovs-dev-bounces@openvswitch.org;\n\treceiver=<UNKNOWN>)", "ext-mx02.extmail.prod.ext.phx2.redhat.com;\n\tdmarc=none (p=none dis=none) header.from=redhat.com", "ext-mx02.extmail.prod.ext.phx2.redhat.com;\n\tspf=fail smtp.mailfrom=mmichels@redhat.com" ], "Received": [ "from mail.linuxfoundation.org (mail.linuxfoundation.org\n\t[140.211.169.12])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xnbpL5gzlz9t3F\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 7 Sep 2017 07:10:34 +1000 (AEST)", "from mail.linux-foundation.org (localhost [127.0.0.1])\n\tby mail.linuxfoundation.org (Postfix) with ESMTP id 2E05BB9B;\n\tWed, 6 Sep 2017 21:08:47 +0000 (UTC)", "from smtp1.linuxfoundation.org (smtp1.linux-foundation.org\n\t[172.17.192.35])\n\tby mail.linuxfoundation.org (Postfix) with ESMTPS id 1A878B4C\n\tfor <dev@openvswitch.org>; Wed, 6 Sep 2017 21:08:45 +0000 (UTC)", "from mx1.redhat.com (mx1.redhat.com [209.132.183.28])\n\tby smtp1.linuxfoundation.org (Postfix) with ESMTPS id 672A9488\n\tfor <dev@openvswitch.org>; Wed, 6 Sep 2017 21:08:44 +0000 (UTC)", "from smtp.corp.redhat.com\n\t(int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby mx1.redhat.com (Postfix) with ESMTPS id D1F72859F7\n\tfor <dev@openvswitch.org>; Wed, 6 Sep 2017 21:08:43 +0000 (UTC)", "from monae.redhat.com (ovpn-121-224.rdu2.redhat.com\n\t[10.10.121.224])\n\tby smtp.corp.redhat.com (Postfix) with ESMTP id 4D913179D3\n\tfor <dev@openvswitch.org>; Wed, 6 Sep 2017 21:08:43 +0000 (UTC)" ], "X-Greylist": [ "domain auto-whitelisted by SQLgrey-1.7.6", "Sender IP whitelisted, not delayed by milter-greylist-4.5.16\n\t(mx1.redhat.com [10.5.110.26]);\n\tWed, 06 Sep 2017 21:08:43 +0000 (UTC)" ], "DMARC-Filter": "OpenDMARC Filter v1.3.2 mx1.redhat.com D1F72859F7", "From": "Mark Michelson <mmichels@redhat.com>", "To": "dev@openvswitch.org", "Date": "Wed, 6 Sep 2017 16:08:38 -0500", "Message-Id": "<20170906210839.26091-4-mmichels@redhat.com>", "In-Reply-To": "<20170906210839.26091-1-mmichels@redhat.com>", "References": "<20170906210839.26091-1-mmichels@redhat.com>", "X-Scanned-By": "MIMEDefang 2.79 on 10.5.11.14", "X-Spam-Status": "No, score=-5.0 required=5.0 tests=RCVD_IN_DNSWL_HI,\n\tRP_MATCHES_RCVD autolearn=disabled version=3.3.1", "X-Spam-Checker-Version": "SpamAssassin 3.3.1 (2010-03-16) on\n\tsmtp1.linux-foundation.org", "Subject": "[ovs-dev] [PATCH 3/4] ovn: Allow northd to install IPv6 ct_lb\n\tlogical flows.", "X-BeenThere": "ovs-dev@openvswitch.org", "X-Mailman-Version": "2.1.12", "Precedence": "list", "List-Id": "<ovs-dev.openvswitch.org>", "List-Unsubscribe": "<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n\t<mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>", "List-Archive": "<http://mail.openvswitch.org/pipermail/ovs-dev/>", "List-Post": "<mailto:ovs-dev@openvswitch.org>", "List-Help": "<mailto:ovs-dev-request@openvswitch.org?subject=help>", "List-Subscribe": "<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n\t<mailto:ovs-dev-request@openvswitch.org?subject=subscribe>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Sender": "ovs-dev-bounces@openvswitch.org", "Errors-To": "ovs-dev-bounces@openvswitch.org" }, "content": "For this commit, ovn-northd will now accept both IPv4 and IPv6 addresses\nin the northbound database for a load balancer VIP or destination\naddresses. For IPv4, the behavior remains the same. For IPv6, the\nfollowing logical flows will be added to the southbound database:\n\n* An ND_NA response for incoming ND_NS requests for the load balancer\n VIP.\n* A ct_lb flow with the configured IPv6 addresses.\n\nSigned-off-by: Mark Michelson <mmichels@redhat.com>\n---\n ovn/northd/ovn-northd.c | 170 ++++++++++++++++++++++++++++--------------------\n 1 file changed, 101 insertions(+), 69 deletions(-)", "diff": "diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c\nindex 49e4ac338..c8b4e4d4f 100644\n--- a/ovn/northd/ovn-northd.c\n+++ b/ovn/northd/ovn-northd.c\n@@ -1562,11 +1562,11 @@ join_logical_ports(struct northd_context *ctx,\n \n static void\n ip_address_and_port_from_lb_key(const char *key, char **ip_address,\n- uint16_t *port);\n+ uint16_t *port, int *addr_family);\n \n static void\n get_router_load_balancer_ips(const struct ovn_datapath *od,\n- struct sset *all_ips)\n+ struct sset *all_ips, int *addr_family)\n {\n if (!od->nbr) {\n return;\n@@ -1582,7 +1582,8 @@ get_router_load_balancer_ips(const struct ovn_datapath *od,\n char *ip_address = NULL;\n uint16_t port;\n \n- ip_address_and_port_from_lb_key(node->key, &ip_address, &port);\n+ ip_address_and_port_from_lb_key(node->key, &ip_address, &port,\n+ addr_family);\n if (!ip_address) {\n continue;\n }\n@@ -1659,7 +1660,8 @@ get_nat_addresses(const struct ovn_port *op, size_t *n)\n \n /* A set to hold all load-balancer vips. */\n struct sset all_ips = SSET_INITIALIZER(&all_ips);\n- get_router_load_balancer_ips(op->od, &all_ips);\n+ int addr_family;\n+ get_router_load_balancer_ips(op->od, &all_ips, &addr_family);\n \n const char *ip_address;\n SSET_FOR_EACH (ip_address, &all_ips) {\n@@ -2889,44 +2891,33 @@ build_pre_acls(struct ovn_datapath *od, struct hmap *lflows)\n * 'ip_address'. */\n static void\n ip_address_and_port_from_lb_key(const char *key, char **ip_address,\n- uint16_t *port)\n+ uint16_t *port, int *addr_family)\n {\n- char *ip_str, *start, *next;\n- *ip_address = NULL;\n- *port = 0;\n+ struct sockaddr_storage ss;\n+ char ip_addr_buf[INET6_ADDRSTRLEN];\n+ char *error;\n \n- next = start = xstrdup(key);\n- ip_str = strsep(&next, \":\");\n- if (!ip_str || !ip_str[0]) {\n- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);\n- VLOG_WARN_RL(&rl, \"bad ip address for load balancer key %s\", key);\n- free(start);\n- return;\n- }\n-\n- ovs_be32 ip, mask;\n- char *error = ip_parse_masked(ip_str, &ip, &mask);\n- if (error || mask != OVS_BE32_MAX) {\n+ error = ipv46_parse(key, PORT_OPTIONAL, &ss);\n+ if (error) {\n static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);\n- VLOG_WARN_RL(&rl, \"bad ip address for load balancer key %s\", key);\n- free(start);\n+ VLOG_WARN_RL(&rl, \"bad ip address or port for load balancer key %s\",\n+ key);\n free(error);\n return;\n }\n \n- int l4_port = 0;\n- if (next && next[0]) {\n- if (!str_to_int(next, 0, &l4_port) || l4_port < 0 || l4_port > 65535) {\n- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);\n- VLOG_WARN_RL(&rl, \"bad ip port for load balancer key %s\", key);\n- free(start);\n- return;\n- }\n+ if (ss.ss_family == AF_INET) {\n+ struct sockaddr_in *sin = ALIGNED_CAST(struct sockaddr_in *, &ss);\n+ *port = sin->sin_port == 0 ? 0 : ntohs(sin->sin_port);\n+ inet_ntop(AF_INET, &sin->sin_addr, ip_addr_buf, sizeof ip_addr_buf);\n+ } else {\n+ struct sockaddr_in6 *sin6 = ALIGNED_CAST(struct sockaddr_in6 *, &ss);\n+ *port = sin6->sin6_port == 0 ? 0 : ntohs(sin6->sin6_port);\n+ inet_ntop(AF_INET6, &sin6->sin6_addr, ip_addr_buf, sizeof ip_addr_buf);\n }\n \n- *port = l4_port;\n- *ip_address = strdup(ip_str);\n- free(start);\n+ *ip_address = xstrdup(ip_addr_buf);\n+ *addr_family = ss.ss_family;\n }\n \n /*\n@@ -2954,6 +2945,7 @@ build_pre_lb(struct ovn_datapath *od, struct hmap *lflows)\n \n struct sset all_ips = SSET_INITIALIZER(&all_ips);\n bool vip_configured = false;\n+ int addr_family = AF_INET;\n for (int i = 0; i < od->nbs->n_load_balancer; i++) {\n struct nbrec_load_balancer *lb = od->nbs->load_balancer[i];\n struct smap *vips = &lb->vips;\n@@ -2965,7 +2957,8 @@ build_pre_lb(struct ovn_datapath *od, struct hmap *lflows)\n /* node->key contains IP:port or just IP. */\n char *ip_address = NULL;\n uint16_t port;\n- ip_address_and_port_from_lb_key(node->key, &ip_address, &port);\n+ ip_address_and_port_from_lb_key(node->key, &ip_address, &port,\n+ &addr_family);\n if (!ip_address) {\n continue;\n }\n@@ -2987,7 +2980,13 @@ build_pre_lb(struct ovn_datapath *od, struct hmap *lflows)\n * packet to conntrack for defragmentation. */\n const char *ip_address;\n SSET_FOR_EACH(ip_address, &all_ips) {\n- char *match = xasprintf(\"ip && ip4.dst == %s\", ip_address);\n+ char *match;\n+\n+ if (addr_family == AF_INET) {\n+ match = xasprintf(\"ip && ip4.dst == %s\", ip_address);\n+ } else {\n+ match = xasprintf(\"ip && ip6.dst == %s\", ip_address);\n+ }\n ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_LB,\n 100, match, REGBIT_CONNTRACK_DEFRAG\" = 1; next;\");\n free(match);\n@@ -3445,10 +3444,12 @@ build_stateful(struct ovn_datapath *od, struct hmap *lflows)\n \n SMAP_FOR_EACH (node, vips) {\n uint16_t port = 0;\n+ int addr_family;\n \n /* node->key contains IP:port or just IP. */\n char *ip_address = NULL;\n- ip_address_and_port_from_lb_key(node->key, &ip_address, &port);\n+ ip_address_and_port_from_lb_key(node->key, &ip_address, &port,\n+ &addr_family);\n if (!ip_address) {\n continue;\n }\n@@ -3456,7 +3457,11 @@ build_stateful(struct ovn_datapath *od, struct hmap *lflows)\n /* New connections in Ingress table. */\n char *action = xasprintf(\"ct_lb(%s);\", node->value);\n struct ds match = DS_EMPTY_INITIALIZER;\n- ds_put_format(&match, \"ct.new && ip4.dst == %s\", ip_address);\n+ if (addr_family == AF_INET) {\n+ ds_put_format(&match, \"ct.new && ip4.dst == %s\", ip_address);\n+ } else {\n+ ds_put_format(&match, \"ct.new && ip6.dst == %s\", ip_address);\n+ }\n if (port) {\n if (lb->protocol && !strcmp(lb->protocol, \"udp\")) {\n ds_put_format(&match, \" && udp.dst == %d\", port);\n@@ -4564,36 +4569,55 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,\n \n /* A set to hold all load-balancer vips that need ARP responses. */\n struct sset all_ips = SSET_INITIALIZER(&all_ips);\n- get_router_load_balancer_ips(op->od, &all_ips);\n+ int addr_family;\n+ get_router_load_balancer_ips(op->od, &all_ips, &addr_family);\n \n const char *ip_address;\n SSET_FOR_EACH(ip_address, &all_ips) {\n- ovs_be32 ip;\n- if (!ip_parse(ip_address, &ip) || !ip) {\n- continue;\n- }\n-\n ds_clear(&match);\n- ds_put_format(&match,\n- \"inport == %s && arp.tpa == \"IP_FMT\" && arp.op == 1\",\n- op->json_key, IP_ARGS(ip));\n+ if (addr_family == AF_INET) {\n+ ds_put_format(&match,\n+ \"inport == %s && arp.tpa == %s && arp.op == 1\",\n+ op->json_key, ip_address);\n+ } else {\n+ ds_put_format(&match,\n+ \"inport == %s && nd_ns && nd.target == %s\",\n+ op->json_key, ip_address);\n+ }\n \n ds_clear(&actions);\n- ds_put_format(&actions,\n+ if (addr_family == AF_INET) {\n+ ds_put_format(&actions,\n \"eth.dst = eth.src; \"\n \"eth.src = %s; \"\n \"arp.op = 2; /* ARP reply */ \"\n \"arp.tha = arp.sha; \"\n \"arp.sha = %s; \"\n \"arp.tpa = arp.spa; \"\n- \"arp.spa = \"IP_FMT\"; \"\n+ \"arp.spa = %s; \"\n \"outport = %s; \"\n \"flags.loopback = 1; \"\n \"output;\",\n op->lrp_networks.ea_s,\n op->lrp_networks.ea_s,\n- IP_ARGS(ip),\n+ ip_address,\n op->json_key);\n+ } else {\n+ ds_put_format(&actions,\n+ \"nd_na { \"\n+ \"eth.src = %s; \"\n+ \"ip6.src = %s; \"\n+ \"nd.target = %s; \"\n+ \"nd.tll = %s; \"\n+ \"outport = inport; \"\n+ \"flags.loopback = 1; \"\n+ \"output; \"\n+ \"};\",\n+ op->lrp_networks.ea_s,\n+ ip_address,\n+ ip_address,\n+ op->lrp_networks.ea_s);\n+ }\n ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 90,\n ds_cstr(&match), ds_cstr(&actions));\n }\n@@ -5257,16 +5281,36 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,\n \n SMAP_FOR_EACH (node, vips) {\n uint16_t port = 0;\n+ int addr_family;\n \n /* node->key contains IP:port or just IP. */\n char *ip_address = NULL;\n- ip_address_and_port_from_lb_key(node->key, &ip_address, &port);\n+ ip_address_and_port_from_lb_key(node->key, &ip_address, &port,\n+ &addr_family);\n if (!ip_address) {\n continue;\n }\n \n if (!sset_contains(&all_ips, ip_address)) {\n sset_add(&all_ips, ip_address);\n+ /* If there are any load balancing rules, we should send\n+ * the packet to conntrack for defragmentation and\n+ * tracking. This helps with two things.\n+ *\n+ * 1. With tracking, we can send only new connections to\n+ * pick a DNAT ip address from a group.\n+ * 2. If there are L4 ports in load balancing rules, we\n+ * need the defragmentation to match on L4 ports. */\n+ ds_clear(&match);\n+ if (addr_family == AF_INET) {\n+ ds_put_format(&match, \"ip && ip4.dst == %s\",\n+ ip_address);\n+ } else {\n+ ds_put_format(&match, \"ip && ip6.dst == %s\",\n+ ip_address);\n+ }\n+ ovn_lflow_add(lflows, od, S_ROUTER_IN_DEFRAG,\n+ 100, ds_cstr(&match), \"ct_next;\");\n }\n \n /* Higher priority rules are added for load-balancing in DNAT\n@@ -5278,8 +5322,13 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,\n ds_put_format(&actions, \"ct_lb(%s);\", node->value);\n \n ds_clear(&match);\n- ds_put_format(&match, \"ip && ip4.dst == %s\",\n- ip_address);\n+ if (addr_family == AF_INET) {\n+ ds_put_format(&match, \"ip && ip4.dst == %s\",\n+ ip_address);\n+ } else {\n+ ds_put_format(&match, \"ip && ip6.dst == %s\",\n+ ip_address);\n+ }\n free(ip_address);\n \n if (port) {\n@@ -5298,23 +5347,6 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,\n }\n }\n }\n-\n- /* If there are any load balancing rules, we should send the\n- * packet to conntrack for defragmentation and tracking. This helps\n- * with two things.\n- *\n- * 1. With tracking, we can send only new connections to pick a\n- * DNAT ip address from a group.\n- * 2. If there are L4 ports in load balancing rules, we need the\n- * defragmentation to match on L4 ports. */\n- const char *ip_address;\n- SSET_FOR_EACH(ip_address, &all_ips) {\n- ds_clear(&match);\n- ds_put_format(&match, \"ip && ip4.dst == %s\", ip_address);\n- ovn_lflow_add(lflows, od, S_ROUTER_IN_DEFRAG,\n- 100, ds_cstr(&match), \"ct_next;\");\n- }\n-\n sset_destroy(&all_ips);\n }\n \n", "prefixes": [ "ovs-dev", "3/4" ] }