)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"c369be15c69f9f260951be2eb07c4f2791ab9dde","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"ea5a1cb4_4e5a846f","updated":"2026-01-12 16:28:36.000000000","message":"If a virtual port becomes \u0027bound\u0027, then updates are not processed anymore whenever a port with the allowed-address pair is created as the result of [1] will be empty.\n\n[1] https://opendev.org/openstack/neutron/src/commit/87c337006d9a971d287f86be818de5a3a6ba4e9e/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py#L663-L668","commit_id":"33d8614aa0869aca96f60558c0b933c1f72fa4a1"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"5c49471b0978ed1722c571ac7bdc79672750f3a6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"5108ac9a_db5adbf3","updated":"2026-01-19 11:46:02.000000000","message":"I think this is the best approach, as it best aligns with what is implied in `update_port_precommit`","commit_id":"a94bd168767dfa2cfa2e75829b9212181c551431"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"fdcdb59e31b0cef35d6e78d614c713b40deb0bfa","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"11adac18_f4aa6f3c","updated":"2026-01-30 10:50:37.000000000","message":"the current patchset does it job, so you can use it in the mean time, but i will start working on another approach as suggested by Rodolfo and Slawek.","commit_id":"a94bd168767dfa2cfa2e75829b9212181c551431"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"33eef215007c70034647775d5c16294598647c92","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"ed3c4497_bb0305c5","updated":"2026-02-18 08:39:10.000000000","message":"I now wonder how to handle updates and existing \"virtual\" ports. Maybe we could add something like maintenance task which would find and update all existing \"virtual\" ports port vif_type to that new one. Wdyt?","commit_id":"a3e64fff40ece24999818e8b6d976a334dcf3b16"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"b11f46b0d8bb3e5e9649c7977207d9c127f69c22","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"8dc6d346_03a20836","updated":"2026-02-05 08:01:59.000000000","message":"recheck","commit_id":"a3e64fff40ece24999818e8b6d976a334dcf3b16"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"e0d0ae29d6b6749878216f89c8ae2dfcc2ce4ee8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"8adfe06c_968faf5f","updated":"2026-02-05 14:39:42.000000000","message":"recheck, not related to my change 😊","commit_id":"a3e64fff40ece24999818e8b6d976a334dcf3b16"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"4429189bbf636052f31950cd071ea0b56c66b3f7","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"cce3fb8f_1807d420","in_reply_to":"c42d9dfe_d0d149d4","updated":"2026-02-19 10:27:53.000000000","message":"yeap, it would be something like that, thx a lot","commit_id":"a3e64fff40ece24999818e8b6d976a334dcf3b16"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"9f65da033c39c0ea28f75b87c22c59f270115532","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"c42d9dfe_d0d149d4","in_reply_to":"ed3c4497_bb0305c5","updated":"2026-02-18 10:16:39.000000000","message":"Hmm, yes, i like the idea. Over time the virtual ports would be updated accordingly, but to have it immediately fixed upon start of neutron-server that would increase the user experience.\n\nfrom what i assume, it is adding a new method (with the decorators) in `neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb.maintenance.DBInconsistenciesPeriodics`? and then raising a NeverAgain exception when done, right? (like the `check_global_dhcp_opts` method)","commit_id":"a3e64fff40ece24999818e8b6d976a334dcf3b16"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"0e6b921afedc9b5d039ea0c960b40f69d5fa2506","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"0bb026d9_f1582d72","updated":"2026-02-17 15:50:41.000000000","message":"I expect zuul to fail, as the neutron-lib is most likely not using the dependant changes right now.","commit_id":"a07ea3135a9e4cd7d70d69d13cf25791c4ec4039"},{"author":{"_account_id":16011,"name":"James Denton","email":"james.denton@outlook.com","username":"busterswt"},"change_message_id":"cdcec61f6f2164db76068c4dedc31c0fe2be8987","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"3ade3562_718cd9a5","updated":"2026-03-03 22:32:44.000000000","message":"FWIW, we just implemented this patch to resolve the same issue with both STANDALONE and ACTIVE_STANDBY Octavia loadbalancers seen in both 2024.1 and 2025.1. Happy to report that it appears effective in restoring connectivity post-failover.","commit_id":"9ed73b08333e0102e89fad6a3598d77539d037a6"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"e6da0ecf7263c1ce6574ca08dede15bd7f84f6ae","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":6,"id":"e2d8b369_aa7bd265","updated":"2026-03-09 16:05:44.000000000","message":"ill admit i dont fully follow all the details of this patch\nas i have not had time to fully load all the context but\ni just dont want to end up breaking the standard usecase where we reseve virtual ips by creating neutron port without attachign them to any host or vm\n\nthen add the ip to N nuetorn ports via allowed adress pairs but importantly do not seting the binding.host value in the prot.\n\ni.e. as a normal user of an openstack cloud today i can deploy k8s by and with metallb, reservice an ip for the metalb to provide to my ingress server and assing that ip in the allowed adress pairs on my worker vms\n\nthis is very similar to the ovn loadblanacer flow but the imporant thing is the prot will never be bound to a host and the tarffic shoudl flow based on mac learning to the active metal lb instance when its in arp mode.\n\nits not clear to me if https://bugs.launchpad.net/neutron/+bug/2125573/comments/2  was referring to the admin sate on the unbound port or the port associated with the vms.\n\nit woudl be unreasonable for the admin state on the unbound port to affect the bound port or the taffic to its ip allowed via allowed_addresspair but changing the admin state on the port assigned to the vm shoudl obviously affect the traffic.\n\nthe admin state also shoudl not prevent port binding or neutron sending network-vif-plugged event it just controls if the network backend shoudl drop traffic or not. it should not prevent the standard ovn mechanism driver form binding the port if the host is set.","commit_id":"9ed73b08333e0102e89fad6a3598d77539d037a6"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"01168c8d966c18403e31cc444ada77ff6aaffd59","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"d24ecff4_c2ee9862","in_reply_to":"3ade3562_718cd9a5","updated":"2026-03-06 14:22:03.000000000","message":"Nice! even though \u0027it works on my dev\u0027 (and our prod environment), it is good to hear it also works as expected for your environment!","commit_id":"9ed73b08333e0102e89fad6a3598d77539d037a6"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"ef359dc4fdcb7fe2bfdda183b574408c3064c2aa","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":6,"id":"6c801882_64abbac2","in_reply_to":"3e6e8d84_49954778","updated":"2026-03-09 22:13:36.000000000","message":"yeah, i kind of figured you meant the metallb driver for k8s (not a neutron driver 😊)\n\n\n\u003e neutron shoudl not be seting a host, specificly the binding:host_id on an unbound port ever in resonce ot info form ovn.\n\nFor virtual ports this is already the case (that behaviour is not changed with this patch, the host_id was already populated for virtual ports (needed for other integrations)). \nThough, what this patch does change, is setting the vif_type to virtual as well, as this kind of port actually _is_ managed by the neutron backend. As you mentioned before, this virtual port is not attached directly to an instance or anything.\n\n\n\u003e by the way part of the reason im consderd about htis si\n\u003e https://github.com/openstack/nova/commit/4eef0fe6354304b4639a3b635e4955457188e4ce\n\u003e\n\u003e nova didn used to corectly unbind a shelve vm form its host\n\u003e we fixted that a number of year ago but of a tenant happned to add the ip adress of a port assocated with a shelve instance it must not result in that port beign bound ot a host with a virtual vif_type.\n\nA virtual port is not bound to an instance (and nova does not do anything with with it, right?), so can you explain to me in which situation this does apply to virtual ports?\nThis change only applies to the VIP/reserved port, not the port attached to an instance.\n\n\n\u003e correalating neutron prot via ip adress adn alowed_adress_paris is fagile, to my knoladge we have never prevented you form ahaving allowed_adress_paris refer to an ip of a diffent neutron port presiscely for the the case of reservicing an ip\n\nMaybe i am not understanding it correctly, but hasn\u0027t this always been the case with allowed-address-pairs? And it is also required to make it work in OVN, if you want to have an Floating IP associated to an VIP. \nHow would you otherwise configure the required NAT rule?\n\n\u003e so this propsoal feels liek a breaking api change. i.e. that allowed_adress_pairs on one port can have any effect on anoher.\n\u003e that feels invlid to me\n\nWith OVN (and also Tungsten fabric and probably/possibly other SDN\u0027s) this has always been the case, as changing allowed-address-pairs on a port directly influences the port security of the port.\n\nI do not see how this change is changing or breaking the API, but please let me know if you discover the scenario.\n\n\u003e i think we need a better fix for octaivias problem\n\nI do not think so, as this patch fixes the issue, but if you have another idea how to resolve this, please let me know!","commit_id":"9ed73b08333e0102e89fad6a3598d77539d037a6"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"eadb0026b63581b99bf5609bf6054a57ff4b4b9b","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":6,"id":"f3207ee0_fe804255","in_reply_to":"42ef568f_84a9814f","updated":"2026-03-09 18:57:45.000000000","message":"note when i said metallb above im not refireing to a metallb driver\n\nimf referign to someone installing metlb in there vm with on intergriton with neutron beyond adding teh adress pair adn creating a neutorn port to hold the ip.\n\n\nneutron shoudl not be seting a host, specificly the binding:host_id on an unbound port ever in resonce ot info form ovn.\n\nwe have a mechanium to activete port binding based on ovn reciving packets but neutron cannot modify the boundhost based on packets that woudl regresss the security model.\n\nneutorn is only allowed to process info for host where a port binding has been created via the rest api. that was part of the security model for live migration to ensure we do not allow packets to egree form arbiray host only the host that have a port bidnign or are refenced in teh migrating_to filed.","commit_id":"9ed73b08333e0102e89fad6a3598d77539d037a6"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"974c78c0a808531f0b06f506821f86779b6e7bcf","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":6,"id":"7c36148a_6308ab9c","in_reply_to":"6c801882_64abbac2","updated":"2026-03-10 11:55:21.000000000","message":"```\n    correalating neutron prot via ip adress adn alowed_adress_paris is fagile, to my knoladge we have never prevented you form ahaving allowed_adress_paris refer to an ip of a diffent neutron port presiscely for the the case of reservicing an ip\n\nMaybe i am not understanding it correctly, but hasn\u0027t this always been the case with allowed-address-pairs? And it is also required to make it work in OVN, if you want to have an Floating IP associated to an VIP.\nHow would you otherwise configure the required NAT rule?\n```\n\nthe behaviour of allowed address pairs need to be consistent between drivers\n\nwith ml2/ovs there is no nat rule to configure or openflow rules to install at the ovs level.\n\nallowed_address_pairs is a firewall configuration to allow egress of the relevent ip/mac adress to bypass the mac/ip anti spoffing flows that woudl otherwise result in the egress (vm to vswich) packet being drop\n\nit was never intened to configure routing or ingress traffic to the vm.\n\nthe association of the ip is learded purly based on the mac learning frames such as RARP packets sent on the port.\nml2/ovn should not work any differently.,\n\nso allowed_adress_pairs 192.168.50.100 on port A cannot have an effect on port B with that ip by changing its bind_host and vif_type to viurtual.\n\nas far as i was aware it was not possible to have a neutron floating ip assocated with the unbound port in the past and that was by design.\nto make that work you woudl have had to have implement the nat in teh l3 namespace of the router but i dont think the l3 agent ever did that. of ovn it woudl similar have to do the nat internally in its router implementation but i dont se how it could compute the oepnflow rules without usign the learn action or similar to understand which chassi the ip was last seen on.\n\ni mean neutron/ovn could do that. have flows that match on the allows address pairs on egress and update the chassis and then install a higher priority flow for subsequent packets but that should not update the host on the neutron port.\n\ni can summerise my 2 main concerns\n```\n1 mech driver should never modify binding:host_id that shoudl only ever be done by a service like octvia or nova or ironic. never neutron\n2 allowed_address_paris on Port A cannot have an impact on the state of port B\n```\nlets tkae a simpel 3 port exampel\n\nport  A (192.168.50.10) and port B (192.168.50.20)  are both attached to two seperate vms\n\nPort V (192.168.50.250) is a unbound unatted port that i will used for a VIP adress\n\nassume port a and its vm are on host A and port B and its vm are on host B\n\nif i update both port a and port b  with allowed_adress_pair\u003d192.168.50.250\n\nbut i have never egressed a packet on that ip what host id and vif type would port V have?\n\nnext i next i send a burst of traffic form 192.168.58.250 from port A for 5 second then port B for 5 second and back and forth\nare you going to continusly rebind Port V updating its host in the neutron db over and over agin.\n\nthat seams like a great way to ddos the neutron server and its db.\n\na better way to do this IMO would be ot have a vnic_type\u003dvirtual or device_owner:octavia and some way to refence the specific neuton port that this vif is assocated with. if you combine that with multiple port binding (the feature that was added for live migration to allow modeling a port that is attached on multiple hosts) and create one port binding per host that it can route to that will result in the lsp in ovn having all relevent chassies listed in allowed_chassis allowing egress from all of them if requried. you can use the packet activation mode ot update the active port binding on packet egress to redirect ingress traffic to the new primary host or you can mange the primary host manyally form ocatia by activating the prot binding for the port/host you care about.\n\noctavia can specify the correlation via the binding:profile or more cleanly via a new neutron extion to allow normal user to do the same thign without requireing the service/admin role\n\nthat woudl allow you to properly model a vip port providing a standard way to do that officaly in neutron(vnic_type\u003dvirutal), the assocation between that vip port and the ports it is allowed to egress form, it would allow you to contol the primary ingress port  so you can steer traffinc or leave teh backend update that based on packet egress. it woudl also allow you to assocate a neutron floating ip to expose it to the internet and implement routing in the l3 agent or in the sdn contoler in the case of ovn or calico.\n\nyou would still have to use allowed_adress_pairs to all egress on the non vip port but if we had this as a first class concept you could define that port refence via a vip port automaticlly allow that vip.\n\ni know that is a big depatrue form the current patch but this really does not sound like a bug to me this is very much a feature and api change in my view.\n\nam i missing or not understanding something?","commit_id":"9ed73b08333e0102e89fad6a3598d77539d037a6"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"03e39ac2f79b5f5065f8ebd24e954ac47cfca55d","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":6,"id":"c6cdffe5_4bccab4e","in_reply_to":"7c36148a_6308ab9c","updated":"2026-03-10 16:34:46.000000000","message":"Well, that is more than i bargained for, thank you! 😄\n\nLet me start with saying, that I am not currently aware how allowed-address-pairs (AAP) is implemented in code for other drivers than OVN. What i do know (from previous experience with linux-bridge and OVS implementation), is that AAP on a port only changes the port security on that port. AAP itself does not make NAT rules or anything.\n\nBut what you can do (and i have done in the past 10 years), is to create a port with the IP you use in the AAP (your port V), and then assign a floating ip to port V. This floating IP does create NAT rules (i mean that is what floating ips are for, right?).\nHow this internal virtual ip is resolved, is up to the backend (e.g. OVS / OVN / other SDN); typically by learning the RARP on one of the member ports (e.g. the ports with AAP configured).\n\nI think this is the correct way and most clean way to do it, as all three ports (port A, port B and port V) are member of the same subnet, and a router is also a member of a subnet with its gateway port.\n\nSo far i think we can agree on how AAP and floating ip\u0027s are used, right?\n\n\u003e as far as i was aware it was not possible to have a neutron floating ip assocated with the unbound port in the past and that was by design.\n\nIt is possible (and to my knowledge the only way to create a loadbalancer through a floating ip)\n\n\u003e i can summerise my 2 main concerns\n\u003e ```\n1 mech driver should never modify binding:host_id that shoudl only ever be done by a service like octvia or nova or ironic. never neutron\n2 allowed_address_paris on Port A cannot have an impact on the state of port B\n```\n\n1. while i do agree for ports attached directly to a device (e.g. device_id is populated), i do not agree for the virtual port scenario, as the network backend is in control of where the virtual ip is attached (as it basically follows a parent port that advertises the IP using ARP).\n2. agree, that is not what is happening here. Only port V is updated\n\n\u003e if i update both port a and port b with allowed_adress_pair\u003d192.168.50.250\n\u003e but i have never egressed a packet on that ip what host id and vif type would port V have?\n\nvif type would be unbound, and host_id is empty, as neither port has advertised the IP yet.\n\n\u003e that seams like a great way to ddos the neutron server and its db.\n\nWhat you are referring to is either a active-active virtual ip (which is not supported by OVN) or some erroroneous configuration that would failover the ip continuously. Lets just agree that in normal situation, the virtual ip either lives on port A, or on port B, not both and is able to migrate beween the ports in case of downtime or maintenance.\n\nSo when port A is taking ownership of the virtual ip, port V is updated by OVN to reflect which port is the current owner of the virtual ip. Once OVN has updated that information, neutron now processes this event and sets the host_id in the portbinding neutron db for port V.\n\n\u003e octavia can specify the correlation via the binding:profile or more cleanly via a new neutron extion to allow normal user to do the same thign without requireing the service/admin role\n\nThere is already a direct correlation available, using the subnet of all three ports, so why not use it? (and it is already used and implemented). By introducing yet another API endpoint, where also end users need to configure a direct relation between port A+B and port Y to make virtual ports work, seems like a excaggeration and complexification toward endusers when setting up simple haproxy/keepalived setups (as it currently works with AAP, port V and a floating ip attached to port V).\n\nI mean, sure for octavia purposes you can implement/hide this hurdle without hurting end-users, but when customers want to do the loadbalancing themselves on their own instances, running haproxy and keepalived, it introduces just another hurdle to use openstack and push them towards other non-openstack solutions.\n\n\n\u003e am i missing or not understanding something?\n\nmaybe we took a wrong turn, where i implied that AAP on one port changes something on another port. While this is true for port V, this obviously does not apply to port B, when updating AAP on port A.\n\n\u003e i know that is a big depatrue form the current patch but this really does not sound like a bug to me this is very much a feature and api change in my view.\n\nThe change you are proposing is deviates a lot from this change, and imho does not apply to this change. I do not have the cards here to make that change for you, so i would suggest you bring it up in a neutron weekly meeting or something similar if you want such API implemented.\n\nThis patch is only to fix the current implementation and to update port V in the portbinding from Unbound to Virtual, once either port A or port B take ownership of the virtual ip.\n\nThis way we can uniquely identify this port to be used as a virtual port and allow updates to the virtual-parent within OVN.\nIt is a new vif_type (peer reviewed by the neutron core devs) so there is no risk of cross contamination anywhere.","commit_id":"9ed73b08333e0102e89fad6a3598d77539d037a6"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"e9296efce26e9bbb97959fc2de2f3d9028be4288","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"42ef568f_84a9814f","in_reply_to":"e2d8b369_aa7bd265","updated":"2026-03-09 17:24:47.000000000","message":"In short, this change does not change any behaviour within OVN, it just clarifies the API, and fixes an issue when the VIP port was updated and had host information in the port binding state.\n\n\nI think the metallb driver does exactly the same as Octavia, as the octavia driver also creates one port for the VIP (reserved port), to be discovered using ARP. The hostname is set by the neutron server, based on the information provided from the ovn-controller.\n\nOnce a arp reply packet is received from a port with the ip address of the vip in the allowed address pairs. OVN controller will \u0027claim/bind\u0027 the vip port to the discoverd port that sent the arp reply.\nThis event is processed by neutron, and the host_id is populated. (this procedure is exactly the same for metallb as for octavia).\n\nWith the change i\u0027ve written here, is that we also change the `binding:vif_type` to `virtual` (this new vif type in neutron-lib has been merged last week). This makes the port appear bound, while in reality it is not bound directly to one instance, as it will still follow the ARP replies, on the ports with the IP in the allowed-address-pairs.\n\nYou _can_ still bind it to an instance (i guess, i would not recommend it), but typically this is prevented by setting a device_owner in the properties of the vip port.","commit_id":"9ed73b08333e0102e89fad6a3598d77539d037a6"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"9b00df26c204d4eae1997210dcb89318047076aa","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":6,"id":"3e6e8d84_49954778","in_reply_to":"f3207ee0_fe804255","updated":"2026-03-09 19:09:10.000000000","message":"by the way part of the reason im consderd about htis si \n\nhttps://github.com/openstack/nova/commit/4eef0fe6354304b4639a3b635e4955457188e4ce\n\nnova didn used to corectly unbind a shelve vm form its host\n\nwe fixted that a number of year ago but\n\nof a tenant happned to add the ip adress of a port  assocated with a shelve instance it must not result in that port beign bound ot a host with a virtual vif_type.\n\n\ncorrealating neutron prot via ip adress adn alowed_adress_paris is fagile\n\nto my knoladge we have never prevented you form ahaving allowed_adress_paris refer to an ip of a diffent neutron port presiscely for the the case of reservicing an ip\n\nso this propsoal feels liek a breaking api change. i.e. that allowed_adress_pairs  on one port can have any effect on anoher.\n\nthat feels invlid to me and i think we need a better fix for octaivias problem","commit_id":"9ed73b08333e0102e89fad6a3598d77539d037a6"}],"neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py":[{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"2eaf2826506afdcc3554add54abefcc2f440ca5c","unresolved":true,"context_lines":[{"line_number":1227,"context_line":""},{"line_number":1228,"context_line":"                    # Fetch the OVN switch port to check if it\u0027s a virtual port"},{"line_number":1229,"context_line":"                    lsp \u003d idlutils.row_by_value(self.sb_ovn, \u0027Port_Binding\u0027,"},{"line_number":1230,"context_line":"                                                \u0027logical_port\u0027, port[\u0027id\u0027])"},{"line_number":1231,"context_line":"                    if lsp and lsp.type \u003d\u003d ovn_const.LSP_TYPE_VIRTUAL:"},{"line_number":1232,"context_line":"                        # We need to set the vif_type to \u0027unbound\u0027 so that"},{"line_number":1233,"context_line":"                        # updates to the port virtual-parents are handled"}],"source_content_type":"text/x-python","patch_set":1,"id":"735079d2_a0e89618","line":1230,"updated":"2026-01-12 22:05:18.000000000","message":"Is it enough to just check if the port has allowed address pairs?\n\nif port.get(\u0027allowed_address_pairs\u0027)\n\nor\n\nutils.get_allowed_address_pairs_ip_addresses(port)","commit_id":"33d8614aa0869aca96f60558c0b933c1f72fa4a1"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"f4af2f568cceb58e92800d639041185b52caa36b","unresolved":true,"context_lines":[{"line_number":1227,"context_line":""},{"line_number":1228,"context_line":"                    # Fetch the OVN switch port to check if it\u0027s a virtual port"},{"line_number":1229,"context_line":"                    lsp \u003d idlutils.row_by_value(self.sb_ovn, \u0027Port_Binding\u0027,"},{"line_number":1230,"context_line":"                                                \u0027logical_port\u0027, port[\u0027id\u0027])"},{"line_number":1231,"context_line":"                    if lsp and lsp.type \u003d\u003d ovn_const.LSP_TYPE_VIRTUAL:"},{"line_number":1232,"context_line":"                        # We need to set the vif_type to \u0027unbound\u0027 so that"},{"line_number":1233,"context_line":"                        # updates to the port virtual-parents are handled"}],"source_content_type":"text/x-python","patch_set":1,"id":"4b8b2ee0_610e6c44","line":1230,"in_reply_to":"735079d2_a0e89618","updated":"2026-01-12 22:48:09.000000000","message":"The port in this context is the VIP port, so it does not have allowed address pairs set (other ports have the allowed address pair set to the ip of this port).\n\nNot sure how the port is otherwise identifiable as the virtual port.\n\nAnother approach might be to change the code at [1], but i am not sure what more safeguards are required there (assuming the filter for unbound port is really required).\n\n[1] https://opendev.org/openstack/neutron/src/commit/87c337006d9a971d287f86be818de5a3a6ba4e9e/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py#L663-L668","commit_id":"33d8614aa0869aca96f60558c0b933c1f72fa4a1"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"6b4b9d535a91fef59e7bd371a82c6bf6becae7f9","unresolved":true,"context_lines":[{"line_number":1228,"context_line":"                    # Fetch the OVN switch port to check if it\u0027s a virtual port"},{"line_number":1229,"context_line":"                    lsp \u003d idlutils.row_by_value(self.sb_ovn, \u0027Port_Binding\u0027,"},{"line_number":1230,"context_line":"                                                \u0027logical_port\u0027, port[\u0027id\u0027])"},{"line_number":1231,"context_line":"                    if lsp and lsp.type \u003d\u003d ovn_const.LSP_TYPE_VIRTUAL:"},{"line_number":1232,"context_line":"                        # We need to set the vif_type to \u0027unbound\u0027 so that"},{"line_number":1233,"context_line":"                        # updates to the port virtual-parents are handled"},{"line_number":1234,"context_line":"                        # correctly when new ports are created (e.g. during"}],"source_content_type":"text/x-python","patch_set":2,"id":"aff98c29_b4233add","line":1231,"range":{"start_line":1231,"start_character":20,"end_line":1231,"end_character":69},"updated":"2026-01-13 14:43:18.000000000","message":"Reading your description in the bug, in particular in [1], doesn\u0027t make sense with the logic that sets a port as UP. That happens when the `PortBindingChassisUpdateEvent` is received but this could not happen while being virtual. So if the port is somehow declared as UP, this is because at some point it was not considered as virtual and another port with this IP address was transmitting traffic.\n\nIs it possible that you can debug all \"port_binding\" events received for this port? Including both `PortBindingChassisUpdateEvent` and `PortBindingUpdateVirtualPortsEvent`. It would be also very useful if you can paste the OVN SB and NB databases just after happening this issue.\n\nIs it possible to replicate this issue somehow?\n\n[1]https://bugs.launchpad.net/octavia/+bug/2125573/comments/7","commit_id":"795bef1f7111afcb55278a6ab1c0c1d81998643b"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"ee426c895131a7b7e94eb118ff056383a37ef4a9","unresolved":true,"context_lines":[{"line_number":1228,"context_line":"                    # Fetch the OVN switch port to check if it\u0027s a virtual port"},{"line_number":1229,"context_line":"                    lsp \u003d idlutils.row_by_value(self.sb_ovn, \u0027Port_Binding\u0027,"},{"line_number":1230,"context_line":"                                                \u0027logical_port\u0027, port[\u0027id\u0027])"},{"line_number":1231,"context_line":"                    if lsp and lsp.type \u003d\u003d ovn_const.LSP_TYPE_VIRTUAL:"},{"line_number":1232,"context_line":"                        # We need to set the vif_type to \u0027unbound\u0027 so that"},{"line_number":1233,"context_line":"                        # updates to the port virtual-parents are handled"},{"line_number":1234,"context_line":"                        # correctly when new ports are created (e.g. during"}],"source_content_type":"text/x-python","patch_set":2,"id":"a04da760_9850d44f","line":1231,"range":{"start_line":1231,"start_character":20,"end_line":1231,"end_character":69},"in_reply_to":"3c70bbe7_5a81b74f","updated":"2026-01-13 15:30:59.000000000","message":"Cleanly (just created) virtual port (virtual-parents were already known)\n```\nmnederlof@host:~$ ovn-nbctl list logical-switch-port 879d551-8c4e-443f-a7ef-93b7630839e6\n\n_uuid               : db5e49b2-be2c-4b57-9946-ec0fee0b695e\naddresses           : [\"fa:16:3e:68:c9:67 10.80.0.77\"]\ndhcpv4_options      : 2538b637-126f-439e-8a04-e92c0c34774d\ndhcpv6_options      : []\ndynamic_addresses   : []\nenabled             : true\nexternal_ids        : {\"neutron:cidrs\"\u003d\"10.80.0.77/24\", \"neutron:device_id\"\u003d\"\", \"neutron:device_owner\"\u003d\"\", \"neutron:mtu\"\u003d\"\", \"neutron:network_name\"\u003dneutron-2c2cf4b0-8d06-4380-a9c1-d8783a02d184, \"neutron:port_capabilities\"\u003d\"\", \"neutron:p\nort_name\"\u003dvip-test, \"neutron:project_id\"\u003d\"\u003cproject\u003e\", \"neutron:revision_number\"\u003d\"1\", \"neutron:security_group_ids\"\u003d\"2efb2963-acd5-4f80-aaee-b0fb89d10a06\", \"neutron:subnet_pool_addr_scope4\"\u003d\"\", \"neutron:subnet_pool_\naddr_scope6\"\u003d\"\", \"neutron:vnic_type\"\u003dnormal}\nha_chassis_group    : []\nmirror_rules        : []\nname                : \"3879d551-8c4e-443f-a7ef-93b7630839e6\"\noptions             : {virtual-ip\u003d\"10.80.0.77\", virtual-parents\u003d\"e5b4fb4a-55fe-47df-aa1a-2022ba9c0190,765c90a9-4e8e-48ed-ac18-e383d64c14a8\"}\nparent_name         : []\nport_security       : [\"fa:16:3e:68:c9:67 10.80.0.77\"]\ntag                 : []\ntag_request         : []\ntype                : virtual\nup                  : false\n\nmnederlof@host:~$ openstack port show 3879d551-8c4e-443f-a7ef-93b7630839e6\n+-------------------------+--------------------------------------------------------------------------------------------------+\n| Field                   | Value                                                                                            |\n+-------------------------+--------------------------------------------------------------------------------------------------+\n| admin_state_up          | UP                                                                                               |\n| allowed_address_pairs   |                                                                                                  |\n| binding_host_id         |                                                                                                  |\n| binding_profile         |                                                                                                  |\n| binding_vif_details     |                                                                                                  |\n| binding_vif_type        | unbound                                                                                          |\n| binding_vnic_type       | normal                                                                                           |\n| created_at              | 2026-01-13T15:14:07Z                                                                             |\n| dns_assignment          | fqdn\u003d\u0027host-10-80-0-77.acc1.resource.cloud.\u0027, hostname\u003d\u0027host-10-80-0-77\u0027, ip_address\u003d\u002710.80.0.77\u0027 |\n| fixed_ips               | ip_address\u003d\u002710.80.0.77\u0027, subnet_id\u003d\u0027665ea0d2-31d6-4982-8486-a38d532a7754\u0027                        |\n| id                      | 3879d551-8c4e-443f-a7ef-93b7630839e6                                                             |\n| mac_address             | fa:16:3e:68:c9:67                                                                                |\n| name                    | vip-test                                                                                         |\n| network_id              | 2c2cf4b0-8d06-4380-a9c1-d8783a02d184                                                             |\n| revision_number         | 1                                                                                                |\n| status                  | DOWN                                                                                             |\n| updated_at              | 2026-01-13T15:14:07Z                                                                             |\n+-------------------------+--------------------------------------------------------------------------------------------------+\n\n```\nNow i send out an arp using `arping -I ens3 -s 10.80.0.77 -A 10.80.0.77 -c 1`\n- OVN now goes to UP, and neutron adds host_id information\n\n```\n## changed (OVN):\n\nexternal_ids        : {\"neutron:cidrs\"\u003d\"10.80.0.77/24\", \"neutron:device_id\"\u003d\"\", \"neutron:device_owner\"\u003d\"\", \"neutron:host_id\"\u003dc8fa2, \"neutron:mtu\"\u003d\"\", \"neutron:network_name\"\u003dneutron-2c2cf4b0-8d06-4380-a9c1-d8783a02d184, \"neutron:port_capabilities\"\u003d\"\", \"neutron:port_name\"\u003dvip-test, \"neutron:project_id\"\u003d\"\u003cproject\u003e\", \"neutron:revision_number\"\u003d\"3\", \"neutron:security_group_ids\"\u003d\"2efb2963-acd5-4f80-aaee-b0fb89d10a06\", \"neutron:subnet_pool_addr_scope4\"\u003d\"\", \"neutron:subnet_pool_addr_scope6\"\u003d\"\", \"neutron:vnic_type\"\u003dnormal}\nup                  : true\n\n## Changes (neutron api)\n\nmnederlof@host:~$ openstack port show 3879d551-8c4e-443f-a7ef-93b7630839e6\n+-------------------------+--------------------------------------------------------------------------------------------------+\n| Field                   | Value                                                                                            |\n+-------------------------+--------------------------------------------------------------------------------------------------+\n| admin_state_up          | UP                                                                                               |\n| allowed_address_pairs   |                                                                                                  |\n| binding_host_id         | compute_node1                                                                                    |\n| binding_profile         |                                                                                                  |\n| binding_vif_details     |                                                                                                  |\n| binding_vif_type        | unbound                                                                                          |\n| binding_vnic_type       | normal                                                                                           |\n| created_at              | 2026-01-13T15:14:07Z                                                                             |\n| revision_number         | 3                                                                                                |\n| updated_at              | 2026-01-13T15:16:02Z                                                                             |\n+-------------------------+--------------------------------------------------------------------------------------------------+\n```\n\nsend an update of the port -- `clients.neutron.update_port(\u00273879d551-8c4e-443f-a7ef-93b7630839e6\u0027, {\u0027port\u0027: {}})`\n- Now no real changes in OVN, but in neutron the port gets binding information and is no longer unbound\n\n```\n## Changes (OVN) (only the revision_number):\n\nexternal_ids        : {\"neutron:cidrs\"\u003d\"10.80.0.77/24\", \"neutron:device_id\"\u003d\"\", \"neutron:device_owner\"\u003d\"\", \"neutron:host_id\"\u003dc8fa2, \"neutron:mtu\"\u003d\"\", \"neutron:network_name\"\u003dneutron-2c2cf4b0-8d06-4380-a9c1-d8783a02d184, \"neutron:port_capabilities\"\u003d\"\", \"neutron:port_name\"\u003dvip-test, \"neutron:project_id\"\u003d\"\u003cproject\u003e\", \"neutron:revision_number\"\u003d\"5\", \"neutron:security_group_ids\"\u003d\"2efb2963-acd5-4f80-aaee-b0fb89d10a06\", \"neutron:subnet_pool_addr_scope4\"\u003d\"\", \"neutron:subnet_pool_addr_scope6\"\u003d\"\", \"neutron:vnic_type\"\u003dnormal}\n\n\n## Changes (neutron api)\nmnederlof@host:~$ openstack port show 3879d551-8c4e-443f-a7ef-93b7630839e6\n+-------------------------+------------------------------------------------------------------------------------------------------------+\n| Field                   | Value                                                                                                      |\n+-------------------------+------------------------------------------------------------------------------------------------------------+\n| admin_state_up          | UP                                                                                                         |\n| allowed_address_pairs   |                                                                                                            |\n| binding_host_id         | compute_node1                                                                                         |\n| binding_profile         |                                                                                                            |\n| binding_vif_details     | bound_drivers.0\u003d\u0027ovn\u0027, bridge_name\u003d\u0027br-int\u0027, connectivity\u003d\u0027l2\u0027, datapath_type\u003d\u0027system\u0027, port_filter\u003d\u0027True\u0027 |\n| binding_vif_type        | ovs                                                                                                        |\n| binding_vnic_type       | normal                                                                                                     |\n| created_at              | 2026-01-13T15:14:07Z                                                                                       |\n| revision_number         | 5                                                                                                          |\n| updated_at              | 2026-01-13T15:20:14Z                                                                                       |\n+-------------------------+------------------------------------------------------------------------------------------------------------+\n```\n(the bind_port method is called per earlier traceback)","commit_id":"795bef1f7111afcb55278a6ab1c0c1d81998643b"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"4d8b160ad9d577a110187b35630ea27a5c893ee9","unresolved":true,"context_lines":[{"line_number":1228,"context_line":"                    # Fetch the OVN switch port to check if it\u0027s a virtual port"},{"line_number":1229,"context_line":"                    lsp \u003d idlutils.row_by_value(self.sb_ovn, \u0027Port_Binding\u0027,"},{"line_number":1230,"context_line":"                                                \u0027logical_port\u0027, port[\u0027id\u0027])"},{"line_number":1231,"context_line":"                    if lsp and lsp.type \u003d\u003d ovn_const.LSP_TYPE_VIRTUAL:"},{"line_number":1232,"context_line":"                        # We need to set the vif_type to \u0027unbound\u0027 so that"},{"line_number":1233,"context_line":"                        # updates to the port virtual-parents are handled"},{"line_number":1234,"context_line":"                        # correctly when new ports are created (e.g. during"}],"source_content_type":"text/x-python","patch_set":2,"id":"cc01e1cd_f2b2b2fb","line":1231,"range":{"start_line":1231,"start_character":20,"end_line":1231,"end_character":69},"in_reply_to":"a04da760_9850d44f","updated":"2026-01-29 15:35:05.000000000","message":"Ok, now I get your point and I think it makes sense. I\u0027m talking to other Neutron developers in order to check if that is something expected or not.","commit_id":"795bef1f7111afcb55278a6ab1c0c1d81998643b"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"ddb6f99c653d928edba193a4190ea97abc8e9538","unresolved":true,"context_lines":[{"line_number":1228,"context_line":"                    # Fetch the OVN switch port to check if it\u0027s a virtual port"},{"line_number":1229,"context_line":"                    lsp \u003d idlutils.row_by_value(self.sb_ovn, \u0027Port_Binding\u0027,"},{"line_number":1230,"context_line":"                                                \u0027logical_port\u0027, port[\u0027id\u0027])"},{"line_number":1231,"context_line":"                    if lsp and lsp.type \u003d\u003d ovn_const.LSP_TYPE_VIRTUAL:"},{"line_number":1232,"context_line":"                        # We need to set the vif_type to \u0027unbound\u0027 so that"},{"line_number":1233,"context_line":"                        # updates to the port virtual-parents are handled"},{"line_number":1234,"context_line":"                        # correctly when new ports are created (e.g. during"}],"source_content_type":"text/x-python","patch_set":2,"id":"cb931f3e_5c332709","line":1231,"range":{"start_line":1231,"start_character":20,"end_line":1231,"end_character":69},"in_reply_to":"aff98c29_b4233add","updated":"2026-01-13 14:54:25.000000000","message":"i have a captured stacktrace even. this port binding happens during a port update of the VIP port (which octavia does before starting a failover).\n\nstacktrace: \n```\n2026-01-12 15:24:55.797 29 INFO neutron.plugins.ml2.drivers.ovn.mech_driver.mech_driver [None req-e33cb87c-f5a9-4bc3-8a56-499602ae1bf8 33be9567730c46c2a86b72bb82330372 XLIS - - 62fc3390f98c430cb786b45ad3b5c035 62fc3390f98c430cb786b45ad3b5c035] !! \n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/eventlet/greenthread.py\", line 272, in main\n    result \u003d function(*args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/eventlet/wsgi.py\", line 905, in process_request\n    self.protocol(conn_state, self)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/eventlet/wsgi.py\", line 363, in __init__\n    self.handle()\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/eventlet/wsgi.py\", line 396, in handle\n    self.handle_one_request()\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/eventlet/wsgi.py\", line 492, in handle_one_request\n    self.handle_one_response()\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/eventlet/wsgi.py\", line 614, in handle_one_response\n    result \u003d self.application(self.environ, start_response)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/paste/urlmap.py\", line 211, in __call__\n    return app(environ, start_response)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 129, in __call__\n    resp \u003d self.call_func(req, *args, **kw)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 193, in call_func\n    return self.func(req, *args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/oslo_middleware/base.py\", line 124, in __call__\n    response \u003d req.get_response(self.application)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/request.py\", line 1313, in send\n    status, headers, app_iter \u003d self.call_application(\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/request.py\", line 1278, in call_application\n    app_iter \u003d application(self.environ, start_response)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 129, in __call__\n    resp \u003d self.call_func(req, *args, **kw)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 193, in call_func\n    return self.func(req, *args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/oslo_middleware/base.py\", line 124, in __call__\n    response \u003d req.get_response(self.application)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/request.py\", line 1313, in send\n    status, headers, app_iter \u003d self.call_application(\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/request.py\", line 1278, in call_application\n    app_iter \u003d application(self.environ, start_response)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 129, in __call__\n    resp \u003d self.call_func(req, *args, **kw)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 193, in call_func\n    return self.func(req, *args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/oslo_middleware/request_id.py\", line 58, in __call__\n    response \u003d req.get_response(self.application)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/request.py\", line 1313, in send\n    status, headers, app_iter \u003d self.call_application(\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/request.py\", line 1278, in call_application\n    app_iter \u003d application(self.environ, start_response)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 129, in __call__\n    resp \u003d self.call_func(req, *args, **kw)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 193, in call_func\n    return self.func(req, *args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/oslo_middleware/catch_errors.py\", line 40, in __call__\n    response \u003d req.get_response(self.application)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/request.py\", line 1313, in send\n    status, headers, app_iter \u003d self.call_application(\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/request.py\", line 1278, in call_application\n    app_iter \u003d application(self.environ, start_response)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 129, in __call__\n    resp \u003d self.call_func(req, *args, **kw)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 193, in call_func\n    return self.func(req, *args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/osprofiler/web.py\", line 111, in __call__\n    return request.get_response(self.application)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/request.py\", line 1313, in send\n    status, headers, app_iter \u003d self.call_application(\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/request.py\", line 1278, in call_application\n    app_iter \u003d application(self.environ, start_response)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 129, in __call__\n    resp \u003d self.call_func(req, *args, **kw)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 193, in call_func\n    return self.func(req, *args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/keystonemiddleware/auth_token/__init__.py\", line 340, in __call__\n    response \u003d req.get_response(self._app)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/request.py\", line 1313, in send\n    status, headers, app_iter \u003d self.call_application(\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/request.py\", line 1278, in call_application\n    app_iter \u003d application(self.environ, start_response)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 143, in __call__\n    return resp(environ, start_response)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 143, in __call__\n    return resp(environ, start_response)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/routes/middleware.py\", line 153, in __call__\n    response \u003d self.app(environ, start_response)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/webob/dec.py\", line 143, in __call__\n    return resp(environ, start_response)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/pecan/middleware/recursive.py\", line 56, in __call__\n    return self.application(environ, start_response)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/pecan/core.py\", line 841, in __call__\n    return super(Pecan, self).__call__(environ, start_response)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/pecan/core.py\", line 682, in __call__\n    self.invoke_controller(controller, args, kwargs, state)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/pecan/core.py\", line 573, in invoke_controller\n    result \u003d controller(*args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron_lib/db/api.py\", line 135, in wrapped\n    return f(*args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/oslo_db/api.py\", line 142, in wrapper\n    return f(*args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron_lib/db/api.py\", line 181, in wrapped\n    return f(*dup_args, **dup_kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron/pecan_wsgi/controllers/utils.py\", line 65, in wrapped\n    return f(*args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron/pecan_wsgi/controllers/resource.py\", line 74, in put\n    return {self.resource: self.plugin_updater(*updater_args)}\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron/common/utils.py\", line 716, in inner\n    return f(*args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron_lib/db/api.py\", line 223, in wrapped\n    return f_with_retry(*args, **kwargs,\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron_lib/db/api.py\", line 135, in wrapped\n    return f(*args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/oslo_db/api.py\", line 142, in wrapper\n    return f(*args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron_lib/db/api.py\", line 181, in wrapped\n    return f(*dup_args, **dup_kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron/plugins/ml2/plugin.py\", line 2061, in update_port\n    bound_context \u003d self._bind_port_if_needed(\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron_lib/db/api.py\", line 135, in wrapped\n    return f(*args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/oslo_db/api.py\", line 142, in wrapper\n    return f(*args, **kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron_lib/db/api.py\", line 181, in wrapped\n    return f(*dup_args, **dup_kwargs)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron/plugins/ml2/plugin.py\", line 629, in _bind_port_if_needed\n    bind_context, need_notify, try_again \u003d self._attempt_binding(\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron/plugins/ml2/plugin.py\", line 663, in _attempt_binding\n    bind_context \u003d self._bind_port(context)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron/plugins/ml2/plugin.py\", line 695, in _bind_port\n    self.mechanism_manager.bind_port(new_context)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron/plugins/ml2/managers.py\", line 820, in bind_port\n    if not self._bind_port_level(context, 0,\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron/plugins/ml2/managers.py\", line 869, in _bind_port_level\n    driver.obj.bind_port(context)\n  File \"/var/lib/kolla/venv/lib/python3.12/site-packages/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py\", line 1168, in bind_port\n    LOG.info(\\\u0027!! %s\\\u0027, traceback.format_stack())\n```","commit_id":"795bef1f7111afcb55278a6ab1c0c1d81998643b"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"43f0740c2735bb54e6c3dbd8c11cad1ae1cb992d","unresolved":true,"context_lines":[{"line_number":1228,"context_line":"                    # Fetch the OVN switch port to check if it\u0027s a virtual port"},{"line_number":1229,"context_line":"                    lsp \u003d idlutils.row_by_value(self.sb_ovn, \u0027Port_Binding\u0027,"},{"line_number":1230,"context_line":"                                                \u0027logical_port\u0027, port[\u0027id\u0027])"},{"line_number":1231,"context_line":"                    if lsp and lsp.type \u003d\u003d ovn_const.LSP_TYPE_VIRTUAL:"},{"line_number":1232,"context_line":"                        # We need to set the vif_type to \u0027unbound\u0027 so that"},{"line_number":1233,"context_line":"                        # updates to the port virtual-parents are handled"},{"line_number":1234,"context_line":"                        # correctly when new ports are created (e.g. during"}],"source_content_type":"text/x-python","patch_set":2,"id":"3c70bbe7_5a81b74f","line":1231,"range":{"start_line":1231,"start_character":20,"end_line":1231,"end_character":69},"in_reply_to":"cb931f3e_5c332709","updated":"2026-01-13 15:00:21.000000000","message":"so in the workflow to reproduce this:\n\n- create a vip port\n- create a \u0027slave\u0027 port with the ip of the vip port in allowed-address-pair\n- bind the slave port to an instance\n- start announcing the ip from the instance (using garp or sending out arp replies)\n- now the vip-port will be \u0027bound\u0027 to the slave port, and the host_id is updated on the vip/virtual port\n- do any update to the vip port (or just send a empty update)\n- above traceback is triggered and we find ourselves in the bind_port method\n\nif this (or the other patch) is not applied, then it is no longer possible to add more virtual-parents to the vip port, as it is now bound with vif_type `ovs` and the filter in [1] will no longer be able to find the virtual port.\n\n[1] https://opendev.org/openstack/neutron/src/commit/87c337006d9a971d287f86be818de5a3a6ba4e9e/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py#L663-L668","commit_id":"795bef1f7111afcb55278a6ab1c0c1d81998643b"},{"author":{"_account_id":36193,"name":"Kevin Schwerdtfeger","display_name":"Kevin Schwerdtfeger","email":"schwerdtfeger.kevin@heb.com","username":"kevin-schwerdtfeger"},"change_message_id":"453587802cb990f3bcec01c3104fe1715928881e","unresolved":true,"context_lines":[{"line_number":1135,"context_line":""},{"line_number":1136,"context_line":"            # As this code might not be called via the binding precommit"},{"line_number":1137,"context_line":"            # hook, we need to validate the binding profile here as well."},{"line_number":1138,"context_line":"            ovn_utils.validate_port_binding_and_virtual_port("},{"line_number":1139,"context_line":"                context, self._plugin, port, original_port)"},{"line_number":1140,"context_line":"        except n_exc.BadRequest as e:"},{"line_number":1141,"context_line":"            # This means the port is type virtual and it should stay unbound"},{"line_number":1142,"context_line":"            LOG.debug(\u0027Refusing to bind port %s: %s\u0027, port[\u0027id\u0027], str(e))"}],"source_content_type":"text/x-python","patch_set":3,"id":"ba74aea4_b29da732","line":1139,"range":{"start_line":1138,"start_character":0,"end_line":1139,"end_character":59},"updated":"2026-01-20 19:43:04.000000000","message":"The validate_port_binding_and_virtual_port method expects 5 parameters to be passed in, only 4 are given here.","commit_id":"a94bd168767dfa2cfa2e75829b9212181c551431"},{"author":{"_account_id":36193,"name":"Kevin Schwerdtfeger","display_name":"Kevin Schwerdtfeger","email":"schwerdtfeger.kevin@heb.com","username":"kevin-schwerdtfeger"},"change_message_id":"a1b83a8acc1a4778e6252e22a5ff84862fb24623","unresolved":false,"context_lines":[{"line_number":1135,"context_line":""},{"line_number":1136,"context_line":"            # As this code might not be called via the binding precommit"},{"line_number":1137,"context_line":"            # hook, we need to validate the binding profile here as well."},{"line_number":1138,"context_line":"            ovn_utils.validate_port_binding_and_virtual_port("},{"line_number":1139,"context_line":"                context, self._plugin, port, original_port)"},{"line_number":1140,"context_line":"        except n_exc.BadRequest as e:"},{"line_number":1141,"context_line":"            # This means the port is type virtual and it should stay unbound"},{"line_number":1142,"context_line":"            LOG.debug(\u0027Refusing to bind port %s: %s\u0027, port[\u0027id\u0027], str(e))"}],"source_content_type":"text/x-python","patch_set":3,"id":"62bd5be3_5591c4bb","line":1139,"range":{"start_line":1138,"start_character":0,"end_line":1139,"end_character":59},"in_reply_to":"7f7ca7f1_204f622a","updated":"2026-01-21 20:22:47.000000000","message":"Thanks for clearing that up.  I was testing this patch against an older release ran into that issue.  For what it\u0027s worth, we were experiencing similar issues as described here and this patch resolved them.","commit_id":"a94bd168767dfa2cfa2e75829b9212181c551431"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"6ffbdddf558f9facafe8cbc022dbb8ea6e5876c0","unresolved":false,"context_lines":[{"line_number":1135,"context_line":""},{"line_number":1136,"context_line":"            # As this code might not be called via the binding precommit"},{"line_number":1137,"context_line":"            # hook, we need to validate the binding profile here as well."},{"line_number":1138,"context_line":"            ovn_utils.validate_port_binding_and_virtual_port("},{"line_number":1139,"context_line":"                context, self._plugin, port, original_port)"},{"line_number":1140,"context_line":"        except n_exc.BadRequest as e:"},{"line_number":1141,"context_line":"            # This means the port is type virtual and it should stay unbound"},{"line_number":1142,"context_line":"            LOG.debug(\u0027Refusing to bind port %s: %s\u0027, port[\u0027id\u0027], str(e))"}],"source_content_type":"text/x-python","patch_set":3,"id":"7f7ca7f1_204f622a","line":1139,"range":{"start_line":1138,"start_character":0,"end_line":1139,"end_character":59},"in_reply_to":"ba74aea4_b29da732","updated":"2026-01-20 19:58:48.000000000","message":"Hi kevin,\n\nfor earlier releases you are right, but in master it is not since this commit [1]. It has recently been updated to a lookup in the neutron db instead of the ovn database.\n\nOnce a change has been approved for this bug, i will create the appropriate backports.\n\nfyi, the correct call for earlier releases is this:\n```\n            ovn_utils.validate_port_binding_and_virtual_port(\n                context, self.nb_ovn, self._plugin, port, original_port)\n```\n\n[1] https://opendev.org/openstack/neutron/commit/5b811fcef52e1d6fe5828389c0bfa5c0c59f1ae3","commit_id":"a94bd168767dfa2cfa2e75829b9212181c551431"},{"author":{"_account_id":8313,"name":"Lajos Katona","display_name":"lajoskatona","email":"katonalala@gmail.com","username":"elajkat","status":"Ericsson Software Technology"},"change_message_id":"0d09d9944b99f149a3378f451819c04300d74abf","unresolved":true,"context_lines":[{"line_number":1139,"context_line":"                context, self._plugin, port, original_port)"},{"line_number":1140,"context_line":"        except n_exc.BadRequest as e:"},{"line_number":1141,"context_line":"            # This means the port is type virtual and it should stay unbound"},{"line_number":1142,"context_line":"            LOG.debug(\u0027Refusing to bind port %s: %s\u0027, port[\u0027id\u0027], str(e))"},{"line_number":1143,"context_line":""},{"line_number":1144,"context_line":"            # To prevent the binding_failed (and retrying) we set the"},{"line_number":1145,"context_line":"            # binding to unbound for all segments and be done."}],"source_content_type":"text/x-python","patch_set":3,"id":"5d251c28_91f15f3d","line":1142,"updated":"2026-01-23 10:57:20.000000000","message":"Refusing to bind port as it is virtual to be clear in the log, though the exception might guide the reader .","commit_id":"a94bd168767dfa2cfa2e75829b9212181c551431"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"12ae7364729f5a8aae3d2dbac76d1d6c3b915cb5","unresolved":true,"context_lines":[{"line_number":1139,"context_line":"                context, self._plugin, port, original_port)"},{"line_number":1140,"context_line":"        except n_exc.BadRequest as e:"},{"line_number":1141,"context_line":"            # This means the port is type virtual and it should stay unbound"},{"line_number":1142,"context_line":"            LOG.debug(\u0027Refusing to bind port %s: %s\u0027, port[\u0027id\u0027], str(e))"},{"line_number":1143,"context_line":""},{"line_number":1144,"context_line":"            # To prevent the binding_failed (and retrying) we set the"},{"line_number":1145,"context_line":"            # binding to unbound for all segments and be done."}],"source_content_type":"text/x-python","patch_set":3,"id":"e66372f6_8b7d5088","line":1142,"in_reply_to":"5d251c28_91f15f3d","updated":"2026-01-26 10:50:34.000000000","message":"The debug message would be:\n`Refusing to bind port \u003cuuid\u003e: Bad port request: A virtual logical switch port cannot be bound to a host`\n\nSo if that is not clear enough, then please let me know what we can do to make it clearer 😊","commit_id":"a94bd168767dfa2cfa2e75829b9212181c551431"},{"author":{"_account_id":8313,"name":"Lajos Katona","display_name":"lajoskatona","email":"katonalala@gmail.com","username":"elajkat","status":"Ericsson Software Technology"},"change_message_id":"931718b9ea08200a140b082a84b4d2543eceaf30","unresolved":true,"context_lines":[{"line_number":1139,"context_line":"                context, self._plugin, port, original_port)"},{"line_number":1140,"context_line":"        except n_exc.BadRequest as e:"},{"line_number":1141,"context_line":"            # This means the port is type virtual and it should stay unbound"},{"line_number":1142,"context_line":"            LOG.debug(\u0027Refusing to bind port %s: %s\u0027, port[\u0027id\u0027], str(e))"},{"line_number":1143,"context_line":""},{"line_number":1144,"context_line":"            # To prevent the binding_failed (and retrying) we set the"},{"line_number":1145,"context_line":"            # binding to unbound for all segments and be done."}],"source_content_type":"text/x-python","patch_set":3,"id":"20fdabf9_88dd17f5","line":1142,"in_reply_to":"e66372f6_8b7d5088","updated":"2026-01-29 09:56:00.000000000","message":"ah, ok so the exception contains that it is a virtual port","commit_id":"a94bd168767dfa2cfa2e75829b9212181c551431"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"4d8b160ad9d577a110187b35630ea27a5c893ee9","unresolved":true,"context_lines":[{"line_number":1143,"context_line":""},{"line_number":1144,"context_line":"            # To prevent the binding_failed (and retrying) we set the"},{"line_number":1145,"context_line":"            # binding to unbound for all segments and be done."},{"line_number":1146,"context_line":"            for segment_to_bind in context.segments_to_bind:"},{"line_number":1147,"context_line":"                context.set_binding(segment_to_bind[api.ID],"},{"line_number":1148,"context_line":"                                    portbindings.VIF_TYPE_UNBOUND, {})"},{"line_number":1149,"context_line":"            return"},{"line_number":1150,"context_line":""},{"line_number":1151,"context_line":"        # OVN chassis information is needed to ensure a valid port bind."},{"line_number":1152,"context_line":"        # Collect port binding data and refuse binding if the OVN chassis"}],"source_content_type":"text/x-python","patch_set":3,"id":"10426fd2_e5fa8cdc","line":1149,"range":{"start_line":1146,"start_character":13,"end_line":1149,"end_character":18},"updated":"2026-01-29 15:35:05.000000000","message":"While this is working, I would suggest something different. When the virtual port is updated with the host_id, in `PortBindingUpdateVirtualPortsEvent`, we can also set a different `vif_type`. I tested with an empty string but we should find something different (\u0027virtual`, for example). That will prevent the port binding of this port. At the same time, when the port is no longer virtual, we should restore the `unbound` vif type.","commit_id":"a94bd168767dfa2cfa2e75829b9212181c551431"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"19981bf430e2cd879ac6ddebd564eeadb88b3438","unresolved":true,"context_lines":[{"line_number":1143,"context_line":""},{"line_number":1144,"context_line":"            # To prevent the binding_failed (and retrying) we set the"},{"line_number":1145,"context_line":"            # binding to unbound for all segments and be done."},{"line_number":1146,"context_line":"            for segment_to_bind in context.segments_to_bind:"},{"line_number":1147,"context_line":"                context.set_binding(segment_to_bind[api.ID],"},{"line_number":1148,"context_line":"                                    portbindings.VIF_TYPE_UNBOUND, {})"},{"line_number":1149,"context_line":"            return"},{"line_number":1150,"context_line":""},{"line_number":1151,"context_line":"        # OVN chassis information is needed to ensure a valid port bind."},{"line_number":1152,"context_line":"        # Collect port binding data and refuse binding if the OVN chassis"}],"source_content_type":"text/x-python","patch_set":3,"id":"99e31aea_997d1baa","line":1149,"range":{"start_line":1146,"start_character":13,"end_line":1149,"end_character":18},"in_reply_to":"10426fd2_e5fa8cdc","updated":"2026-01-30 09:54:59.000000000","message":"I agree with Rodolfo that having new vif_type would be good here. That way we would clearly show even in the API what is the purpose of such port and could avoid such issues like the one which this patch is trying to fix","commit_id":"a94bd168767dfa2cfa2e75829b9212181c551431"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"4418b593724d9641f179cb86bb5a0f957fe2da31","unresolved":true,"context_lines":[{"line_number":1143,"context_line":""},{"line_number":1144,"context_line":"            # To prevent the binding_failed (and retrying) we set the"},{"line_number":1145,"context_line":"            # binding to unbound for all segments and be done."},{"line_number":1146,"context_line":"            for segment_to_bind in context.segments_to_bind:"},{"line_number":1147,"context_line":"                context.set_binding(segment_to_bind[api.ID],"},{"line_number":1148,"context_line":"                                    portbindings.VIF_TYPE_UNBOUND, {})"},{"line_number":1149,"context_line":"            return"},{"line_number":1150,"context_line":""},{"line_number":1151,"context_line":"        # OVN chassis information is needed to ensure a valid port bind."},{"line_number":1152,"context_line":"        # Collect port binding data and refuse binding if the OVN chassis"}],"source_content_type":"text/x-python","patch_set":3,"id":"7fdd45a9_38f921c7","line":1149,"range":{"start_line":1146,"start_character":13,"end_line":1149,"end_character":18},"in_reply_to":"167ee246_1a3b17b0","updated":"2026-02-17 15:06:03.000000000","message":"I brought this topic to the Neutron meeting [1]. The \"virtual\" type seems to be a supported option to the detriment of \"distributed\". I insist in creating a new \"virtual\" type only for the virtual ports.\n\n[1]https://meetings.opendev.org/meetings/networking/2026/networking.2026-02-17-14.01.log.html#l-140","commit_id":"a94bd168767dfa2cfa2e75829b9212181c551431"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"f3c663104417094f9ea9fe7201e2c7868764c427","unresolved":false,"context_lines":[{"line_number":1143,"context_line":""},{"line_number":1144,"context_line":"            # To prevent the binding_failed (and retrying) we set the"},{"line_number":1145,"context_line":"            # binding to unbound for all segments and be done."},{"line_number":1146,"context_line":"            for segment_to_bind in context.segments_to_bind:"},{"line_number":1147,"context_line":"                context.set_binding(segment_to_bind[api.ID],"},{"line_number":1148,"context_line":"                                    portbindings.VIF_TYPE_UNBOUND, {})"},{"line_number":1149,"context_line":"            return"},{"line_number":1150,"context_line":""},{"line_number":1151,"context_line":"        # OVN chassis information is needed to ensure a valid port bind."},{"line_number":1152,"context_line":"        # Collect port binding data and refuse binding if the OVN chassis"}],"source_content_type":"text/x-python","patch_set":3,"id":"b8ed52f9_ac6358a9","line":1149,"range":{"start_line":1146,"start_character":13,"end_line":1149,"end_character":18},"in_reply_to":"7fdd45a9_38f921c7","updated":"2026-02-17 15:28:05.000000000","message":"Ack, i will change it to virtual 😊","commit_id":"a94bd168767dfa2cfa2e75829b9212181c551431"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"99d2e12333c7964f239e8a2cc74b47cba4cce857","unresolved":true,"context_lines":[{"line_number":1143,"context_line":""},{"line_number":1144,"context_line":"            # To prevent the binding_failed (and retrying) we set the"},{"line_number":1145,"context_line":"            # binding to unbound for all segments and be done."},{"line_number":1146,"context_line":"            for segment_to_bind in context.segments_to_bind:"},{"line_number":1147,"context_line":"                context.set_binding(segment_to_bind[api.ID],"},{"line_number":1148,"context_line":"                                    portbindings.VIF_TYPE_UNBOUND, {})"},{"line_number":1149,"context_line":"            return"},{"line_number":1150,"context_line":""},{"line_number":1151,"context_line":"        # OVN chassis information is needed to ensure a valid port bind."},{"line_number":1152,"context_line":"        # Collect port binding data and refuse binding if the OVN chassis"}],"source_content_type":"text/x-python","patch_set":3,"id":"fbe344fd_ff70bd33","line":1149,"range":{"start_line":1146,"start_character":13,"end_line":1149,"end_character":18},"in_reply_to":"99e31aea_997d1baa","updated":"2026-01-30 10:49:05.000000000","message":"Ah yes, that sounds like a good plan, then the port might not even be considered to be bound, and we do not get in that function as well. I will start working on this idea.","commit_id":"a94bd168767dfa2cfa2e75829b9212181c551431"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"c7468601537f0f4170ad4943e2d3555324f2c2b7","unresolved":true,"context_lines":[{"line_number":1143,"context_line":""},{"line_number":1144,"context_line":"            # To prevent the binding_failed (and retrying) we set the"},{"line_number":1145,"context_line":"            # binding to unbound for all segments and be done."},{"line_number":1146,"context_line":"            for segment_to_bind in context.segments_to_bind:"},{"line_number":1147,"context_line":"                context.set_binding(segment_to_bind[api.ID],"},{"line_number":1148,"context_line":"                                    portbindings.VIF_TYPE_UNBOUND, {})"},{"line_number":1149,"context_line":"            return"},{"line_number":1150,"context_line":""},{"line_number":1151,"context_line":"        # OVN chassis information is needed to ensure a valid port bind."},{"line_number":1152,"context_line":"        # Collect port binding data and refuse binding if the OVN chassis"}],"source_content_type":"text/x-python","patch_set":3,"id":"167ee246_1a3b17b0","line":1149,"range":{"start_line":1146,"start_character":13,"end_line":1149,"end_character":18},"in_reply_to":"fbe344fd_ff70bd33","updated":"2026-02-04 10:55:00.000000000","message":"As i was reviewing the current set of portbindings, i noticed there was already a portbinding vif_type called distributed, which could make sense for virtual ports. \n\nTherefore i chose this one for this new change, as that would also prevent another change for the `neutron-lib` repo.\n\nI have searched the code to see where it was already used, but only found this one used in the DVR usecase, which is not conflicting with these virtual ports imho.\n\nIf you really want a new vif_type this can still be done obviously, but i like this distributed one too as the virtual port can be seen as some \u0027floating\u0027 ip which binds to the host which is advertising the virtual ip.\n\nAnyway, i like this new approach, works well from what i\u0027ve tested in our environment.","commit_id":"a94bd168767dfa2cfa2e75829b9212181c551431"}],"neutron/plugins/ml2/plugin.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"e6da0ecf7263c1ce6574ca08dede15bd7f84f6ae","unresolved":true,"context_lines":[{"line_number":2167,"context_line":"        register is always VIF_TYPE_UNBOUND. However this method updates the"},{"line_number":2168,"context_line":"        host information to reflect where the associated port that is sending"},{"line_number":2169,"context_line":"        or receiving traffic, using the VIP address, is hosted."},{"line_number":2170,"context_line":"        If hosted, the portbinding will change to VIF_TYPE_VIRTUAL. This"},{"line_number":2171,"context_line":"        will prevent other mechanism drivers from attempting to bind the port."},{"line_number":2172,"context_line":"        \"\"\""},{"line_number":2173,"context_line":"        hostname \u003d hostname or \u0027\u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"1d11aa65_6166fdb9","line":2170,"range":{"start_line":2170,"start_character":11,"end_line":2170,"end_character":17},"updated":"2026-03-09 16:05:44.000000000","message":"```suggestion\n        If bound to a host, the portbinding will change to VIF_TYPE_VIRTUAL. This\n```\n\ni..e if bind_details:host is set to a non empty value.\n\nthat is only settable by an admin/service so i guess that will not break the usecase todya hwere people create neutron port and intentionally leave them unattached and unbound to resver ips.\n\ni was orgianlly going to suggest that this shoudl not be a new VIF_TYPE but woudl be better to model as a new vnic_type\n\nif it was a vnic type it woudl allow normal usser to trivally create prots to reserve ips and you could still enfoce that they could not be bound to a nova instance for example.\n\noctavia could do that for its loadbalnce ip reservation but its more explcit then having it be a sideffect of having host set but device_owner of device_id unset.","commit_id":"9ed73b08333e0102e89fad6a3598d77539d037a6"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"e9296efce26e9bbb97959fc2de2f3d9028be4288","unresolved":false,"context_lines":[{"line_number":2167,"context_line":"        register is always VIF_TYPE_UNBOUND. However this method updates the"},{"line_number":2168,"context_line":"        host information to reflect where the associated port that is sending"},{"line_number":2169,"context_line":"        or receiving traffic, using the VIP address, is hosted."},{"line_number":2170,"context_line":"        If hosted, the portbinding will change to VIF_TYPE_VIRTUAL. This"},{"line_number":2171,"context_line":"        will prevent other mechanism drivers from attempting to bind the port."},{"line_number":2172,"context_line":"        \"\"\""},{"line_number":2173,"context_line":"        hostname \u003d hostname or \u0027\u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"d2b45f1e_80673225","line":2170,"range":{"start_line":2170,"start_character":11,"end_line":2170,"end_character":17},"in_reply_to":"1d11aa65_6166fdb9","updated":"2026-03-09 17:24:47.000000000","message":"i think vnic types are reserved for other usecases than this one, as that has to do with mechanism drivers to bind a port, which is not different here; it still should be a ovn/ovs port.\n\nIf you want to prevent the port to be bound by an instance, you could populate the `device_owner` with some arbitrary value. I have been using this method already for over a decade.","commit_id":"9ed73b08333e0102e89fad6a3598d77539d037a6"},{"author":{"_account_id":25468,"name":"Michel Nederlof","email":"michel@nederlof.info","username":"pellucid"},"change_message_id":"ef359dc4fdcb7fe2bfdda183b574408c3064c2aa","unresolved":true,"context_lines":[{"line_number":2167,"context_line":"        register is always VIF_TYPE_UNBOUND. However this method updates the"},{"line_number":2168,"context_line":"        host information to reflect where the associated port that is sending"},{"line_number":2169,"context_line":"        or receiving traffic, using the VIP address, is hosted."},{"line_number":2170,"context_line":"        If hosted, the portbinding will change to VIF_TYPE_VIRTUAL. This"},{"line_number":2171,"context_line":"        will prevent other mechanism drivers from attempting to bind the port."},{"line_number":2172,"context_line":"        \"\"\""},{"line_number":2173,"context_line":"        hostname \u003d hostname or \u0027\u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"b5acf67b_67f4f08a","line":2170,"range":{"start_line":2170,"start_character":11,"end_line":2170,"end_character":17},"in_reply_to":"ac3bda10_09f14efd","updated":"2026-03-09 22:13:36.000000000","message":"\u003e project member having asscess to either field is a legacy behvior as those along with bind host are intended to be resoved for service to use.\n\nThe new default still includes `base.NET_OWNER_MEMBER` which allows project members to update the device_owner if the network belongs to the project (e.g. project owned networks)\nAlso, not that this is ontopic for now, but it would be a bad idea if we would remove those rights from project members.\n\n\n\u003e the vif_type is used to model the netowrk backend that will mange teh port\n\u003e the vnic_type are used to mdoel howe the port is assiged to a guest\n\nThe proposed change is actually for a vif_type, as the port is managed by the network backend. E.g. OVN is managing this port and maintaining on which host it is assigned, based on which port sends our the ARP replies.","commit_id":"9ed73b08333e0102e89fad6a3598d77539d037a6"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"eadb0026b63581b99bf5609bf6054a57ff4b4b9b","unresolved":true,"context_lines":[{"line_number":2167,"context_line":"        register is always VIF_TYPE_UNBOUND. However this method updates the"},{"line_number":2168,"context_line":"        host information to reflect where the associated port that is sending"},{"line_number":2169,"context_line":"        or receiving traffic, using the VIP address, is hosted."},{"line_number":2170,"context_line":"        If hosted, the portbinding will change to VIF_TYPE_VIRTUAL. This"},{"line_number":2171,"context_line":"        will prevent other mechanism drivers from attempting to bind the port."},{"line_number":2172,"context_line":"        \"\"\""},{"line_number":2173,"context_line":"        hostname \u003d hostname or \u0027\u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"ac3bda10_09f14efd","line":2170,"range":{"start_line":2170,"start_character":11,"end_line":2170,"end_character":17},"in_reply_to":"d2b45f1e_80673225","updated":"2026-03-09 18:57:45.000000000","message":"the device_owner filed and device_id are ment to be service only\nalthouhg admins can currently set them.\n\n\nhttps://github.com/openstack/neutron/blob/master/neutron/conf/policies/port.py#L84-L117\n\nproject member having asscess to either field is a legacy behvior as those along with bind host are intended to be resoved for service to use.\n\nwhen associated with a nova instance only nova shoudl ever have access to set or modify those values end users shoudl not be able to do it.\n\nml2 drivers can and do supprot multile vnic types.\nso its valid for this to be modeled as a vnic_type or via a diffent atibute on the port.\n\nthe vif_type is used to model the netowrk backend that will mange teh port\nthe vnic_type are used to mdoel howe the port is assiged to a guest\n\ndelcalrign a port \"virutal\" seam much more correct to do via a vinic type to me but ideally neutron woudl have a more native way to reserve ip\n\nusing a port at all is workign around the actual problem of not being able to reservice indivural ips form a subnet.\nit consumes port quota in additon to ip qutoa and mac adresses for example.","commit_id":"9ed73b08333e0102e89fad6a3598d77539d037a6"}]}
