{"id":2235282,"url":"http://patchwork.ozlabs.org/api/patches/2235282/?format=json","web_url":"http://patchwork.ozlabs.org/project/ovn/patch/20260509012348.1485266-1-numans@ovn.org/","project":{"id":68,"url":"http://patchwork.ozlabs.org/api/projects/68/?format=json","name":"Open Virtual Network development","link_name":"ovn","list_id":"ovs-dev.openvswitch.org","list_email":"ovs-dev@openvswitch.org","web_url":"http://openvswitch.org/","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260509012348.1485266-1-numans@ovn.org>","list_archive_url":null,"date":"2026-05-09T01:23:48","name":"[ovs-dev] pinctrl: Use correct IPv6 dst for nd_ns action for IPv4 over v6.","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"c43a7a4b98e270e1412e0fb73a708863eb5ebb0a","submitter":{"id":77669,"url":"http://patchwork.ozlabs.org/api/people/77669/?format=json","name":"Numan Siddique","email":"numans@ovn.org"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/ovn/patch/20260509012348.1485266-1-numans@ovn.org/mbox/","series":[{"id":503473,"url":"http://patchwork.ozlabs.org/api/series/503473/?format=json","web_url":"http://patchwork.ozlabs.org/project/ovn/list/?series=503473","date":"2026-05-09T01:23:48","name":"[ovs-dev] pinctrl: Use correct IPv6 dst for nd_ns action for IPv4 over v6.","version":1,"mbox":"http://patchwork.ozlabs.org/series/503473/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2235282/comments/","check":"warning","checks":"http://patchwork.ozlabs.org/api/patches/2235282/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@legolas.ozlabs.org","ovs-dev@lists.linuxfoundation.org"],"Authentication-Results":["legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=140.211.166.136; helo=smtp3.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)","smtp4.osuosl.org;\n dmarc=none (p=none dis=none) header.from=ovn.org"],"Received":["from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4gC84T1Ls9z1yK7\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 09 May 2026 11:47:19 +1000 (AEST)","from localhost (localhost [127.0.0.1])\n\tby smtp3.osuosl.org (Postfix) with ESMTP id E9B3B61CD3;\n\tSat,  9 May 2026 01:47:16 +0000 (UTC)","from smtp3.osuosl.org ([127.0.0.1])\n by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id 0zCO3r3h11vp; Sat,  9 May 2026 01:47:15 +0000 (UTC)","from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp3.osuosl.org (Postfix) with ESMTPS id BE27361CCD;\n\tSat,  9 May 2026 01:47:15 +0000 (UTC)","from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id 98BCCC04EB;\n\tSat,  9 May 2026 01:47:15 +0000 (UTC)","from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 8B67BC04E7\n for <dev@openvswitch.org>; Sat,  9 May 2026 01:47:13 +0000 (UTC)","from localhost (localhost [127.0.0.1])\n by smtp4.osuosl.org (Postfix) with ESMTP id 7840E42281\n for <dev@openvswitch.org>; Sat,  9 May 2026 01:47:13 +0000 (UTC)","from smtp4.osuosl.org ([127.0.0.1])\n by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id DERi2IVrOJBi for <dev@openvswitch.org>;\n Sat,  9 May 2026 01:47:12 +0000 (UTC)","from mslow3.mail.gandi.net (mslow3.mail.gandi.net [217.70.178.249])\n by smtp4.osuosl.org (Postfix) with ESMTPS id 5D2C342280\n for <dev@openvswitch.org>; Sat,  9 May 2026 01:47:11 +0000 (UTC)","from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net\n [217.70.183.195])\n by mslow3.mail.gandi.net (Postfix) with ESMTP id 6F0BA58044B\n for <dev@openvswitch.org>; Sat,  9 May 2026 01:24:03 +0000 (UTC)","by mail.gandi.net (Postfix) with ESMTPSA id BA1CA1FD22;\n Sat,  9 May 2026 01:23:55 +0000 (UTC)"],"X-Virus-Scanned":["amavis at osuosl.org","amavis at osuosl.org"],"X-Comment":"SPF check N/A for local connections - client-ip=140.211.9.56;\n helo=lists.linuxfoundation.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN> ","DKIM-Filter":["OpenDKIM Filter v2.11.0 smtp3.osuosl.org BE27361CCD","OpenDKIM Filter v2.11.0 smtp4.osuosl.org 5D2C342280"],"Received-SPF":"Pass (mailfrom) identity=mailfrom; client-ip=217.70.178.249;\n helo=mslow3.mail.gandi.net; envelope-from=numans@ovn.org; receiver=<UNKNOWN>","DMARC-Filter":"OpenDMARC Filter v1.4.2 smtp4.osuosl.org 5D2C342280","From":"numans@ovn.org","To":"dev@openvswitch.org","Date":"Fri,  8 May 2026 21:23:48 -0400","Message-ID":"<20260509012348.1485266-1-numans@ovn.org>","X-Mailer":"git-send-email 2.53.0","MIME-Version":"1.0","X-GND-Sasl":"numans@ovn.org","X-GND-State":"clean","X-GND-Score":"-100","X-GND-Cause":"\n dmFkZTGcymBHOwcRdZDzBXRv+5cnB6b4f0W7+9lbU1/WSrj3p8FvNViH6VmVhESihCmb+ij9JEIGrDW4QFXwGAujOG/k2JMArpZCjUezn1XgtmEc1yhGgqW1nzSg47C3+E+kxhxSNSi8VSoYZYYTPFvAiUIdywVVDdN5fBM3Odbpn7N/JAjubLNM6IM3yuaZYN4/e+atC06jSr9+MTK7zMoir5S3vT1FE+hXdNFoFbYkPR807cQjl7FuM5LtMxCZlQK0wl87iTSr9byAHwv/o7thERnMKDMa46AP7L3HAQa84qi/zf4DZElvBhfwaiYExBZlTaZII9asjLfxXzsg2hFpeCceCj8B084Kws/TiFxwzfXi0x7juER2++FAEAOYYIOjNfou9E6y+SGrQ+bFFs/eho/q+MrGNOUckbTMhTvYj+DzeCrQ+6hXafmlpekVV95VkXyINU5PmqVyifWJWMf//doqapObu0K8k7ZD5L8O/JGH0dgiqADinMSpiTG7ooaBaTKKlCg69nBA6TIFsWM/FMr318LIlPB1xFALIQc4IP/mEcOOboiq0CG8RuRIKtnIBwFz/NfHyLtQsDCl1WGemakAisAqz59DfR3EazCi0v5diMEgzHnuF24FS7F775e9fckU3ZkGG/tAB2yZUiP7N5BCZX7WvaCazah2G2A+D8mbyg","Subject":"[ovs-dev] [PATCH ovn] pinctrl: Use correct IPv6 dst for nd_ns\n action for IPv4 over v6.","X-BeenThere":"ovs-dev@openvswitch.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"<ovs-dev.openvswitch.org>","List-Unsubscribe":"<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n <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 <mailto:ovs-dev-request@openvswitch.org?subject=subscribe>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"ovs-dev-bounces@openvswitch.org","Sender":"\"dev\" <ovs-dev-bounces@openvswitch.org>"},"content":"From: Numan Siddique <numans@ovn.org>\n\nIf a logical router with dynamic-routing enabled learns a route\nwhose nexthop is an IPv6 address, then ovn-northd adds a logical\nflow in the lr_in_ip_routing stage, but it doesn't add the\npriority-200 logical flow in lr_in_arp_request to resolve the\nmac of the nexthop. The below prioroty-100 logical flow gets invoked\ninstead.\n\ntable=27(lr_in_arp_request  ), priority=100  ,\n  match=(eth.dst == 00:00:00:00:00:00 && reg9[9] == 0),\n  action=(nd_ns { nd.target = xxreg0; output; }; next;)\n\nAnd this doesn't set the correct Solicit IPv6 destination address.\n\nThis patch fixes the issue in pinctrl handler function for nd_ns\naction by using the IPv6 destination address stored in xxreg0.\nThis action assumes that xxreg0 is populated with the proper address.\n\nOther alternative fix is for ovn-northd to add a logical flow\nin lr_in_arp_request just like it adds for static routes.\n\nI think its better to fix it in pinctrl instead.\n\nFound this issue while testing dynamic routing feature.\n\nAssisted-by: Claude Opus 4.7, Claude Code\nSigned-off-by: Numan Siddique <numans@ovn.org>\n---\n controller/pinctrl.c | 26 +++++++++++------\n tests/ovn.at         | 66 ++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 84 insertions(+), 8 deletions(-)","diff":"diff --git a/controller/pinctrl.c b/controller/pinctrl.c\nindex 1a5407183c..452470ff74 100644\n--- a/controller/pinctrl.c\n+++ b/controller/pinctrl.c\n@@ -6534,17 +6534,27 @@ pinctrl_handle_nd_ns(struct rconn *swconn, const struct flow *ip_flow,\n \n     /* We might be here without actually currently handling an IPv6 packet.\n      * This can happen in the case where we route IPv4 packets over an IPv6\n-     * link.\n-     * In these cases we have no destination IPv6 address from the packet that\n-     * we can reuse. But we receive the actual destination IPv6 address via\n-     * userdata anyway, so what we pass to compose_nd_ns is irrelevant.\n-     * This is just a hope since we do not parse the userdata. If we land here\n-     * for whatever reason without being an IPv6 packet and without userdata we\n-     * will send out a wrong packet.\n-     */\n+     * link (e.g. RFC 5549 / BGP unnumbered, where an IPv4 destination is\n+     * resolved via an IPv6 link-local nexthop).\n+     *\n+     * In that case we have no destination IPv6 address in the trigger packet\n+     * to reuse. compose_nd_ns() needs a valid destination so it can derive\n+     * the correct solicited-node multicast (ff02::1:ff{addr[13:16]}) for\n+     * eth.dst and ip6.dst -- userdata only sets nd.target on the new packet\n+     * and does not rewrite ip6.dst, so a wrong ipv6_dst here egresses on the\n+     * wire as-is.\n+     *\n+     * The fallback nd_ns logical flow in S_ROUTER_IN_ARP_REQUEST stores the\n+     * actual IPv6 nexthop in xxreg0 (REG_NEXT_HOP_IPV6) before invoking the\n+     * nd_ns action, so for the IPv4-over-IPv6 case read xxreg0 from the\n+     * trigger packet's flow metadata. */\n     struct in6_addr ipv6_dst = IN6ADDR_EXACT_INIT;\n     if (get_dl_type(ip_flow) == htons(ETH_TYPE_IPV6)) {\n         ipv6_dst = ip_flow->ipv6_dst;\n+    } else {\n+        ovs_be128 nexthop_be =\n+            hton128(flow_get_xxreg(&pin->flow_metadata.flow, 0));\n+         memcpy(&ipv6_dst, &nexthop_be, sizeof ipv6_dst);\n     }\n     compose_nd_ns(&packet, ip_flow->dl_src, &ipv6_src,\n                   &ipv6_dst);\ndiff --git a/tests/ovn.at b/tests/ovn.at\nindex fbaa63d99c..37e01dc1a9 100644\n--- a/tests/ovn.at\n+++ b/tests/ovn.at\n@@ -46214,3 +46214,69 @@ AT_CHECK([grep -q \"WARN.*dynamic-routing\" hv/ovn-controller.log], [1])\n OVN_CLEANUP([hv])\n AT_CLEANUP\n ])\n+\n+OVN_FOR_EACH_NORTHD([\n+AT_SETUP([IPv4 over v6 Neigh solicitation test])\n+ovn_start\n+\n+net_add n1\n+sim_add hv\n+ovs-vsctl add-br br-phys\n+ovn_attach n1 br-phys 192.168.0.1\n+ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys\n+\n+check ovn-nbctl ls-add sw0\n+check ovn-nbctl lsp-add sw0 sw0-port1\n+check ovn-nbctl lsp-set-addresses sw0-port1 \"50:54:00:00:00:01 10.0.0.3\"\n+\n+check ovn-nbctl lr-add lr0\n+check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24 1000::1/64\n+check ovn-nbctl lsp-add-router-port sw0 sw0-lr0 lr0-sw0\n+\n+check ovn-nbctl ls-add public\n+check ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13\n+check ovn-nbctl lsp-add-router-port public public-lr0 lr0-public\n+\n+# localnet port\n+check ovn-nbctl lsp-add-localnet-port public ln-public phys\n+\n+check ovn-nbctl lrp-set-gateway-chassis lr0-public hv 20\n+check ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.168.0.110 10.0.0.3\n+\n+check ovs-vsctl add-port br-int lsp -- \\\n+    set Interface lsp external_ids:iface-id=lsp\n+\n+ovs-vsctl -- add-port br-int vif1 -- \\\n+    set interface vif1 external-ids:iface-id=sw0-port1 \\\n+    options:tx_pcap=hv/vif1-tx.pcap \\\n+    options:rxq_pcap=hv/vif1-rx.pcap \\\n+    ofport-request=1\n+\n+wait_for_ports_up\n+\n+# Add a learnt route manually\n+dp_uuid=$(fetch_column datapath _uuid external_ids:name=lr0)\n+lrp_uuid=$(fetch_column port_binding _uuid logical_port=lr0-public)\n+\n+ovn-sbctl create learned_route datapath=$dp_uuid logical_port=$lrp_uuid \\\n+ip_prefix=0.0.0.0/0 nexthop='\"fe80::42:ff:fe00:1ff\"'\n+\n+check ovn-nbctl --wait=hv sync\n+\n+# Send an IPv4 packet from sw0-port1 destined to outside\n+packet=$(fmt_pkt \"Ether(dst='00:00:00:00:ff:01', src='50:54:00:00:00:01')/ \\\n+                      IP(dst='8.8.8.8', src='10.0.0.3')/ICMP()\")\n+check as hv ovs-appctl netdev-dummy/receive vif1 $packet\n+\n+nd_ns=$(fmt_pkt \"Ether(dst='33:33:ff:00:01:ff', src='00:00:20:20:12:13')/ \\\n+                       IPv6(src='fe80::200:20ff:fe20:1213', \\\n+                       dst='ff02::1:ff00:1ff')/ICMPv6ND_NS(tgt='fe80::42:ff:fe00:1ff')/\\\n+                       ICMPv6NDOptSrcLLAddr(lladdr='00:00:20:20:12:13')\")\n+\n+echo $nd_ns > expected_nd_ns\n+OVN_CHECK_PACKETS_CONTAIN([hv/br-phys_n1-tx.pcap], [expected_nd_ns])\n+\n+OVN_CLEANUP([hv])\n+AT_CLEANUP\n+])\n+\n","prefixes":["ovs-dev"]}