{"id":554,"date":"2025-11-19T20:22:55","date_gmt":"2025-11-19T20:22:55","guid":{"rendered":"http:\/\/blog.miguelsarmiento.com\/?p=554"},"modified":"2025-11-20T20:33:06","modified_gmt":"2025-11-20T20:33:06","slug":"pve-vxlan-nxos-integration-oh-my","status":"publish","type":"post","link":"https:\/\/blog.miguelsarmiento.com\/?p=554","title":{"rendered":"PVE VXLAN NXOS Integration Oh My!"},"content":{"rendered":"<h1>Introduction<\/h1>\n<p class=\"western\" align=\"left\">The purpose of the following proof of concept is to demonstrate integration between Proxmox PVE and a Cisco 9000v.<\/p>\n<p class=\"western\" align=\"left\"><a href=\"https:\/\/proxmox.com\/en\" target=\"_blank\" rel=\"noopener noreferrer\">PVE<\/a>\u00a0is a fantastic open-source virtualization environment. Recently it has gained a lot of traction in particular with the issues with <a href=\"https:\/\/www.vmware.com\" target=\"_blank\" rel=\"noopener noreferrer\">VSphere<\/a>\u00a0licensing.<\/p>\n<p class=\"western\" align=\"left\">However, while I see several blogs and videos regarding it and in particular its SDN capabilities, I have not seen detail setups involving integration with other SDN devices.<\/p>\n<p class=\"western\" align=\"left\">This is unfortunate since the Cisco 9000 for example is very prevalent and at one point if someone decides to move to PVE, they will need to integrate Cisco or another device to it.<\/p>\n<p class=\"western\" align=\"left\">In any case, from the perspective of learning I think the following will be very instructional.<!--more--><\/p>\n<h1 class=\"western\" align=\"left\">Road Map<\/h1>\n<p class=\"western\" align=\"left\">The intention of this lab is to do provide an example of extending a VXLAN setup from PVE onto a Cisco 9000v.<\/p>\n<p class=\"western\" align=\"left\">The environment and appliances used are the following:<\/p>\n<p class=\"western\" style=\"padding-left: 30px;\" align=\"left\">1) <a href=\"https:\/\/www.eve-ng.net\" target=\"_blank\" rel=\"noopener noreferrer\">EVE-NG<\/a>. Another fantastic open-source\u00a0 application that allows you to create labs and tests configurations. For this proof of concept lab, I am using the latest EVE-NG community edition with 32 GB.<\/p>\n<p class=\"western\" style=\"padding-left: 30px;\" align=\"left\">2) Several Cisco appliances. They include a 3252 image, a 7206 image and a Cisco 9000v running NXOS 9.3.5.<\/p>\n<p class=\"western\" style=\"padding-left: 30px;\" align=\"left\">3) PVE running the latest (as of my writing it was 9.1). It runs the community software. The environment is setup to run containers as devices for testing. Configuring of a cluster is beyond the scope of this lab. There are several blogs and Youtube videos that will point you in the right direction.<\/p>\n<p class=\"western\" align=\"left\">The observant reader will notice that I said containers instead of VMs. The reason is that the PVE instances I am running are inside another hypervisor (ESXI in this case). Because of this PVE will not run VMs in this so called nested-hypervisor environment. However, it can run containers without an issue. I will let the astute reader to realize why this is the case.<\/p>\n<h1 class=\"western\" align=\"left\">Network Diagram<\/h1>\n<p class=\"western\" align=\"left\">Figure 1. shows the network diagram for the lab.<\/p>\n<figure id=\"attachment_584\" aria-describedby=\"caption-attachment-584\" style=\"width: 1920px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/blog.miguelsarmiento.com\/wp-content\/uploads\/2025\/11\/pve-vxlan-nxos-1.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-584\" src=\"https:\/\/blog.miguelsarmiento.com\/wp-content\/uploads\/2025\/11\/pve-vxlan-nxos-1.png\" alt=\"\" width=\"1920\" height=\"1025\" \/><\/a><figcaption id=\"caption-attachment-584\" class=\"wp-caption-text\">Fig. 1. Network Diagram.<\/figcaption><\/figure>\n<p class=\"western\" align=\"left\">A few notes:<\/p>\n<p class=\"western\" style=\"padding-left: 30px;\" align=\"left\">1) MGMT: Management vlan for access via ssh. All nodes are accessible in this fashion only the PVE nodes are shown to make the diagram easier to read.<\/p>\n<p class=\"western\" style=\"padding-left: 30px;\" align=\"left\">2) PVE is a collapsed spine architecture. Some may dispute this however, read the following white paper by <a href=\"https:\/\/www.juniper.net\/documentation\/us\/en\/software\/nce\/nce-178-collapsed-spine-data-center\/topics\/topic-map\/nce-178-collapsed-spine-data-center-overview.html\" target=\"_blank\" rel=\"noopener noreferrer\">Juniper Networks<\/a> that makes this clear in general not just for PVE clusters.<\/p>\n<p class=\"western\" style=\"padding-left: 30px;\" align=\"left\">3) In a real production system, the PVE nodes would access storage over a dedicated network.<\/p>\n<p class=\"western\" style=\"padding-left: 30px;\" align=\"left\">4) Connectivity to the 9000v (leaf-a) would also be on a dedicated network.<\/p>\n<p class=\"western\" style=\"padding-left: 30px;\" align=\"left\">5) Finally, the PVE nodes would also form a cluster on a dedicated network.<\/p>\n<p class=\"western\" align=\"left\">ToR stands for a top-of-the rack switch which will not have VXLAN capabilities however, it will allow you to use the VLANS mapped in the Cisco 9000v.<\/p>\n<h1 class=\"western\" align=\"left\">Configuration<\/h1>\n<h2 class=\"western\" align=\"left\">PVE<\/h2>\n<p class=\"western\" align=\"left\">Configure a normal PVE cluster. Configure SDN,\u00a0 do not create a fabric. The reason will be apparent next and create VXLAN zones as follows:<\/p>\n<p class=\"western\" style=\"padding-left: 30px;\" align=\"left\">1)\u00a0 Create a VXLAN zone for each vxlan you want to use.<\/p>\n<p class=\"western\" style=\"padding-left: 30px;\" align=\"left\">2) Add the three PVE nodes (192.168.1.x) and the loopback IP of the Cisco 9000v. This is important since the VTEPs will establish connections against this IP. In our case we will create two such zones.<\/p>\n<p class=\"western\" style=\"padding-left: 30px;\" align=\"left\">3) VNETS:<\/p>\n<p class=\"western\" style=\"padding-left: 60px;\" align=\"left\">VX1-test: 10.10.1.0\/24 (GW 10.10.1.1) vni:10000.<\/p>\n<p class=\"western\" style=\"padding-left: 60px;\" align=\"left\">VX2-test: 10.10.2.0\/24 (GW 10.10.2.1) vni:15000.<\/p>\n<p class=\"western\" style=\"padding-left: 30px;\" align=\"left\">4) Set the MTU to 9216 for the VNETS to match Cisco\u2019s default.<\/p>\n<p class=\"western\" align=\"left\">The reason for above is that if you were to create a normal fabric using the GUI, when you want to add the Cisco 9000v to the zones you get an error. Try many things to fix it, I finally found in the PVE forums that a patch was issued that allows you to do this. Did not install the patch so I do not know if it actually fixes the issue. Perhaps someone can comment on this.<\/p>\n<p class=\"western\" align=\"left\">Create a file named &#8220;lo&#8221; in \u201c\/etc\/networks\/interfaces.d\/\u201d on all nodes of the cluster.<\/p>\n<p class=\"western\" align=\"left\">Add the following to it:<\/p>\n<pre class=\"western\"><span style=\"font-family: 'DejaVu Sans Mono', monospace;\">iface lo:0 inet static<\/span>\r\n    <span style=\"font-family: 'DejaVu Sans Mono', monospace;\">address 10.10.10.1<\/span>\r\n    <span style=\"font-family: 'DejaVu Sans Mono', monospace;\">netmask 255.255.255.255<\/span>\r\n   <span style=\"font-family: 'DejaVu Sans Mono', monospace;\"># Add a route to 10.10.10.4 via 192.168.1.10<\/span>\r\n    <span style=\"font-family: 'DejaVu Sans Mono', monospace;\">post-up ip route add 10.10.10.4 via 192.168.1.10<\/span>\r\n   <span style=\"font-family: 'DejaVu Sans Mono', monospace;\"># Remove the route when the interface goes down<\/span>\r\n    <span style=\"font-family: 'DejaVu Sans Mono', monospace;\">pre-down ip route del 10.10.10.4 via 192.168.1.10<\/span><\/pre>\n<p class=\"western\" align=\"left\">Replace each IP accordingly, 10.10.10.1,2, and 3 for each node in the cluster. Reboot, better yet restart the network service only.<\/p>\n<p class=\"western\" align=\"left\">After having a working cluster, test that you can create containers in the VXLANs with the IPs in the range describe in (3) above.<\/p>\n<p class=\"western\" align=\"left\">You should be able to ping containers on the same VNIs but not across. You will also notice that even though you can configure a GW and do SNAT, you will not be able to connect outside the cluster.<\/p>\n<p class=\"western\" align=\"left\">This is of course because VXLAN is a layer 2 protocol and thus has no knowledge of layer 3 (i.e. routing).<\/p>\n<h2 class=\"western\">Cisco 9000v<\/h2>\n<p class=\"western\">Configure the Cisco 9000v as follows:<\/p>\n<p><span style=\"font-family: 'Liberation Sans', Arial, sans-serif;\"><span style=\"font-size: large;\">Features<\/span><\/span><\/p>\n<pre class=\"western\"><span style=\"font-family: 'DejaVu Sans Mono', monospace;\">feature ospf<\/span>\r\n<span style=\"font-family: 'DejaVu Sans Mono', monospace;\">feature bgp<\/span>\r\n<span style=\"font-family: 'DejaVu Sans Mono', monospace;\">feature pim<\/span>\r\n<span style=\"font-family: 'DejaVu Sans Mono', monospace;\">feature fabric forwarding<\/span>\r\n<span style=\"font-family: 'DejaVu Sans Mono', monospace;\">feature interface-vlan<\/span>\r\n<span style=\"font-family: 'DejaVu Sans Mono', monospace;\">feature vn-segment-vlan-based<\/span>\r\n<span style=\"font-family: 'DejaVu Sans Mono', monospace;\">feature nv overlay <\/span>\r\n<span style=\"font-family: 'DejaVu Sans Mono', monospace;\">nv overlay evpn<\/span>\r\n<\/pre>\n<p><span style=\"font-family: 'Liberation Sans', Arial, sans-serif;\"><span style=\"font-size: large;\">Interfaces<\/span><\/span><\/p>\n<p>You need a loopback interface (NVE uses it). You also need to assign a MAC address to the interface otherwise you will not be able to communicate with the cluster. Add static routes for the loopback interfaces of the cluster.<\/p>\n<pre class=\"western\"><span style=\"font-family: 'DejaVu Sans Mono', monospace;\">interface loopback0<\/span>\r\n  <span style=\"font-family: 'DejaVu Sans Mono', monospace;\">ip address 10.10.10.4\/32<\/span>\r\n\r\n<span style=\"font-family: 'DejaVu Sans Mono', monospace;\">ip route 10.10.10.1\/32 192.168.1.1<\/span>\r\n<span style=\"font-family: 'DejaVu Sans Mono', monospace;\">ip route 10.10.10.2\/32 192.168.1.2<\/span>\r\n<span style=\"font-family: 'DejaVu Sans Mono', monospace;\">ip route 10.10.10.3\/32 192.168.1.3<\/span>\r\n\r\n<span style=\"font-family: 'DejaVu Sans Mono', monospace;\">interface Ethernet1\/1<\/span>\r\n  <span style=\"font-family: 'DejaVu Sans Mono', monospace;\">no switchport<\/span>\r\n  <span style=\"font-family: 'DejaVu Sans Mono', monospace;\">mac-address 0000.1111.1111<\/span>\r\n  <span style=\"font-family: 'DejaVu Sans Mono', monospace;\">ip address 192.168.1.10\/24<\/span>\r\n  <span style=\"font-family: 'DejaVu Sans Mono', monospace;\">no shutdown<\/span>\r\n  \r\n<span style=\"font-family: 'DejaVu Sans Mono', monospace;\">interface Ethernet1\/2<\/span>\r\n  <span style=\"font-family: 'DejaVu Sans Mono', monospace;\">switchport mode trunk <\/span>\r\n\r\n<span style=\"font-family: 'DejaVu Sans Mono', monospace;\">interface Ethernet1\/3<\/span>\r\n  <span style=\"font-family: 'DejaVu Sans Mono', monospace;\">switchport access vlan 11<\/span>\r\n<\/pre>\n<p><span style=\"font-family: 'Liberation Sans', Arial, sans-serif;\"><span style=\"font-size: large;\">NVE<\/span><\/span><\/p>\n<p>We will do static ingress replication and use the loopback interface as the source for peering.<\/p>\n<pre class=\"western\"><strong><span style=\"font-family: 'DejaVu Sans Mono', monospace;\"><span style=\"font-size: small;\">interface nve1<\/span><\/span>\r\n  <span style=\"font-family: 'DejaVu Sans Mono', monospace;\"><span style=\"font-size: small;\">no shutdown<\/span><\/span>\r\n  <span style=\"font-family: 'DejaVu Sans Mono', monospace;\"><span style=\"font-size: small;\">source-interface loopback0<\/span><\/span>\r\n  <span style=\"font-family: 'DejaVu Sans Mono', monospace;\"><span style=\"font-size: small;\">member vni 15000<\/span><\/span>\r\n    <span style=\"font-family: 'DejaVu Sans Mono', monospace;\"><span style=\"font-size: small;\">ingress-replication protocol static<\/span><\/span>\r\n      <span style=\"font-family: 'DejaVu Sans Mono', monospace;\"><span style=\"font-size: small;\">peer-ip 10.10.10.1<\/span><\/span>\r\n      <span style=\"font-family: 'DejaVu Sans Mono', monospace;\"><span style=\"font-size: small;\">peer-ip 10.10.10.2<\/span><\/span>\r\n      <span style=\"font-family: 'DejaVu Sans Mono', monospace;\"><span style=\"font-size: small;\">peer-ip 10.10.10.3<\/span><\/span>\r\n  <span style=\"font-family: 'DejaVu Sans Mono', monospace;\"><span style=\"font-size: small;\">member vni 10000<\/span><\/span>\r\n    <span style=\"font-family: 'DejaVu Sans Mono', monospace;\"><span style=\"font-size: small;\">ingress-replication protocol static<\/span><\/span>\r\n      <span style=\"font-family: 'DejaVu Sans Mono', monospace;\"><span style=\"font-size: small;\">peer-ip 10.10.10.1<\/span><\/span>\r\n      <span style=\"font-family: 'DejaVu Sans Mono', monospace;\"><span style=\"font-size: small;\">peer-ip 10.10.10.2<\/span><\/span>\r\n      <\/strong><span style=\"font-family: 'DejaVu Sans Mono', monospace;\"><span style=\"font-size: small;\"><strong>peer-ip 10.10.10.3  <\/strong> <\/span><\/span><\/pre>\n<p>Notice that you can have several vnis defined however only one NVE interface (you can only create one!)<\/p>\n<p>Normally you would also use BGP ingress replication which dynamically would learn the VTEPs in use. Here though we do not have an evpn setup.<\/p>\n<p>Also notice that we need connections to all members of the cluster. This would not be necessary if we were using evpn since we will be carrying labels and mac addresses in the payload. That setup would need a route reflector.<\/p>\n<h2>Testing<\/h2>\n<p class=\"western\">Now that you have everything configured you should be able to ping across. I do not show the configuration of the ToR switch. This should be easy to do. I created on the ToR switch a couple of VLAN interfaces with IP 10.10.x.1, they act as gateways for all devices including the containers, I also use NAT to connect to the Internet. Leaf-a and ToR communicate via a trunk port.<\/p>\n<p class=\"western\">Above is left to the reader to configure. If you want inter-container communications, you may have to play with the security settings in the cluster if you cannot ping between containers in different vxlans. This is beyond the scope of this lab.<\/p>\n<p class=\"western\">If you cannot ping the containers make sure that the cluster loopback interfaces can ping the loopback interface of the Cisco. This is because the VTEP tunnels are being established to the Cisco loopback interface. Just re-apply SDN settings this will reload the network in all members.<\/p>\n<p class=\"western\">From PC1:<\/p>\n<pre>pc1#sh ip int bri\r\nInterface IP-Address OK? Method Status Protocol\r\nFastEthernet0\/0 10.10.1.20 YES NVRAM up up \r\nFastEthernet0\/1 unassigned YES NVRAM administratively down down\r\n\r\npc1#sh ip route\r\nCodes: C - connected, S - static, R - RIP, M - mobile, B - BGP\r\n D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area \r\n N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2\r\n E1 - OSPF external type 1, E2 - OSPF external type 2\r\n i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2\r\n ia - IS-IS inter area, * - candidate default, U - per-user static route\r\n o - ODR, P - periodic downloaded static route\r\n\r\nGateway of last resort is 10.10.1.1 to network 0.0.0.0\r\n\r\n10.0.0.0\/24 is subnetted, 1 subnets\r\nC 10.10.1.0 is directly connected, FastEthernet0\/0\r\nS* 0.0.0.0\/0 [1\/0] via 10.10.1.1<\/pre>\n<p class=\"western\">Now ping the container at 10.10.1.10:<\/p>\n<pre>pc1#ping 10.10.1.10\r\n\r\nType escape sequence to abort.\r\nSending 5, 100-byte ICMP Echos to 10.10.1.10, timeout is 2 seconds:\r\n!!!!!\r\nSuccess rate is 100 percent (5\/5), round-trip min\/avg\/max = 4\/8\/12 ms<\/pre>\n<p class=\"western\">From PC2:<\/p>\n<pre>pc2#ping 10.10.1.11\r\n\r\nType escape sequence to abort.\r\nSending 5, 100-byte ICMP Echos to 10.10.1.11, timeout is 2 seconds:\r\n.!!!!\r\nSuccess rate is 80 percent (4\/5), round-trip min\/avg\/max = 8\/14\/20 ms<\/pre>\n<p class=\"western\">IP 10.10.1.11 is a second container configured in the cluster. Finally in the 9k, you can see the NVE peers. They all should be up.<\/p>\n<pre class=\"western\">nxos-9k# show nve peers\r\nInterface Peer-IP State LearnType Uptime Route\r\nr-Mac \r\n--------- -------------------------------------- ----- --------- -------- -----\r\n------------\r\nnve1 192.168.1.1 Up DP 00:11:22 n\/a \r\n \r\nnve1 10.10.10.1 Up DP 02:37:56 n\/a \r\n \r\nnve1 192.168.1.2 Up DP 00:11:34 n\/a \r\n \r\nnve1 10.10.10.2 Up DP 02:37:56 n\/a \r\n \r\nnve1 192.168.1.3 Up DP 00:11:26 n\/a \r\n \r\nnve1 10.10.10.3 Up DP 02:37:56 n\/a \u00a0\r\n\r\n<\/pre>\n<p class=\"western\">You should also be able to ping the Internet since the ToR Switch is doing NAT. Of course in a production system you would not want your tenants to use you as their Internet access.<\/p>\n<p class=\"western\">There you have it. This shows how to extend vxlans, first to a Cisco 9000v and\u00a0 to a top-of-the-rack switch that may not have vxlan capabilities.<\/p>\n<p class=\"western\">This can be done for other devices that support vxlan. It was not as complicated as I though it would be.<\/p>\n<p class=\"western\">Take care,<\/p>\n<p class=\"western\">Ciao.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction The purpose of the following proof of concept is to demonstrate integration between Proxmox PVE and a Cisco 9000v. PVE\u00a0is a fantastic open-source virtualization environment. Recently it has gained a lot of traction in particular with the issues with VSphere\u00a0licensing. However, while I see several blogs and videos regarding it and in particular its &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/blog.miguelsarmiento.com\/?p=554\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;PVE VXLAN NXOS Integration Oh My!&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-554","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blog.miguelsarmiento.com\/index.php?rest_route=\/wp\/v2\/posts\/554","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.miguelsarmiento.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.miguelsarmiento.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.miguelsarmiento.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.miguelsarmiento.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=554"}],"version-history":[{"count":44,"href":"https:\/\/blog.miguelsarmiento.com\/index.php?rest_route=\/wp\/v2\/posts\/554\/revisions"}],"predecessor-version":[{"id":601,"href":"https:\/\/blog.miguelsarmiento.com\/index.php?rest_route=\/wp\/v2\/posts\/554\/revisions\/601"}],"wp:attachment":[{"href":"https:\/\/blog.miguelsarmiento.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=554"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.miguelsarmiento.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=554"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.miguelsarmiento.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=554"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}