, \u00a0meaning our DHCP server will append specific host routes to the DHCP request (via option 121). This results in an additional route being added to the guest, in turn ensuring requests to <\/span>169.254.169.254 are routed via the DHCP agent IP.<\/p>\n$ netstat -nr\r\nKernel IP routing table\r\nDestination Gateway Genmask Flags MSS Window irtt Iface\r\n0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0\r\n169.254.169.254 192.168.1.2 255.255.255.255 UGH 0 0 0 eth0\r\n192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0<\/pre>\nAs you can see the correct route is in place. Lets ping the address to confirm connectivity:<\/span><\/p>\n$ ping 192.168.1.2 -c 2\r\nPING 192.168.1.2 (192.168.1.2): 56 data bytes\r\n64 bytes from 192.168.1.2: seq=0 ttl=64 time=0.768 ms\r\n64 bytes from 192.168.1.2: seq=1 ttl=64 time=0.545 ms\r\nThis all looks good, lets move on.<\/pre>\nThis all looks good, lets move on.<\/p>\n
<\/span>Compute – Bridge Packet Trace<\/span><\/span><\/h2>\nNext we will confirm that traffic is making it out from the instance to the bridge.\u00a0<\/span>There are a few steps in this process. They are:<\/span><\/p>\n<\/span>Confirm Instance Name<\/span><\/span><\/h3>\nIn order to obtain the instance name, we perform a show on the server id. Like so,<\/span><\/p>\nroot@infra1:~# openstack server list\r\n+--------------------------------------+-------------------------+--------+------------------------------------------------------------+------------------------+\r\n| ID | Name | Status | Networks | Image Name |\r\n+--------------------------------------+-------------------------+--------+------------------------------------------------------------+------------------------+ \r\n| d0cebae2-ba1a-45fc-8f11-d28e8fd93ee3 | cirros-DEMO | ACTIVE | tenant_network_lab001-vsrx=192.168.1.50 | cirros |\r\n+--------------------------------------+-------------------------+--------+------------------------------------------------------------+------------------------+\r\n\r\nroot@infra1:~# openstack server show d0cebae2-ba1a-45fc-8f11-d28e8fd93ee3\r\n+-------------------------------------+----------------------------------------------------------+\r\n| Field | Value |\r\n+-------------------------------------+----------------------------------------------------------+\r\n| OS-DCF:diskConfig | MANUAL |\r\n| OS-EXT-AZ:availability_zone | nova |\r\n| OS-EXT-SRV-ATTR:host | compute03 |\r\n| OS-EXT-SRV-ATTR:hypervisor_hostname | compute03 |\r\n| OS-EXT-SRV-ATTR:instance_name | instance-0000001a |\r\n| OS-EXT-STS:power_state | Running |\r\n| OS-EXT-STS:task_state | None |\r\n| OS-EXT-STS:vm_state | active |\r\n| OS-SRV-USG:launched_at | 2017-09-03T06:19:23.000000 |\r\n| OS-SRV-USG:terminated_at | None |\r\n| accessIPv4 | |\r\n| accessIPv6 | |\r\n| addresses | tenant_network_lab001-vsrx=192.168.1.50 |\r\n| config_drive | |\r\n| created | 2017-09-03T06:19:18Z |\r\n| flavor | cirros-small (58772350-942d-442b-9e39-ef953787a2d4) |\r\n| hostId | 57f31ea4cecf1bdae04624374a6db8df774b57e94d8427a8c5f1cff1 |\r\n| id | d0cebae2-ba1a-45fc-8f11-d28e8fd93ee3 |\r\n| image | cirros (5ffaa767-fc80-4d92-90f7-29b6d949797f) |\r\n| key_name | None |\r\n| name | cirros-DEMO |\r\n| progress | 0 |\r\n| project_id | f1eb80264e9c4c688c7603bbb5541396 |\r\n| properties | |\r\n| status | ACTIVE |\r\n| updated | 2017-09-03T06:19:23Z |\r\n| user_id | 85aea2625c7349fc8796527085a04226 |\r\n| volumes_attached | |\r\n+-------------------------------------+----------------------------------------------------------+<\/pre>\n\u00a0From the output can you see the\u00a0<\/span>field OS-EXT-SRV-ATTR:instance_name<\/span> and its value – instance-0000001a<\/span>.<\/span><\/p>\n<\/span>Confirm Bridge Name<\/span><\/span><\/h3>\nUsing the instance_name<\/span> we can then perform a lookup (on the corresponding host) for the bridge. As shown below,<\/span><\/p>\nroot@compute03:~# virsh domiflist instance-0000001a\r\nInterface Type Source Model MAC\r\n--------------------------------------------------------------\r\ntap0e6c063c-48 bridge brq423b2b1b-55 virtio fa:16:3e:92:bd:fd<\/pre>\n<\/span>TCPDump<\/span><\/h3>\nNow we have the bridge name, whilst running another curl from the guest\u00a0we can perform a tcpdump. From this we can see the SYN is sent, but a RST is returned. So we know the traffic from the guest is making it to the attached bridge, however something is preventing the completion of the TCP connection by sending a RST.\u00a0<\/span><\/p>\nroot@compute03:~# tcpdump -ni brq423b2b1b-55\r\ntcpdump: verbose output suppressed, use -v or -vv for full protocol decode\r\nlistening on brq423b2b1b-55, link-type EN10MB (Ethernet), capture size 262144 bytes\r\n22:02:27.792813 IP 192.168.1.50.49513 > 169.254.169.254.80: Flags [S], seq 2770101210, win 14100, options [mss 1410,sackOK,TS val 77970740 ecr 0,nop,wscale 2], length 0\r\n22:02:27.793369 IP 169.254.169.254.80 > 192.168.1.50.49513: Flags [R.], seq 0, ack 2770101211, win 0, length 0<\/pre>\n<\/span>Controller – Neutron DHCP Namespace<\/span><\/span><\/h2>\nWe will now jump into the DHCP namespace. This namespace also hosts the metadata service proxy. \u00a0Once inside we can confirm if the necessary IPs are configured, and also run another tcpdump to see if the traffic is making it in.<\/span><\/p>\nFirst things first, upon the infra node we connect to the neutron_agents_container<\/span>. We confirm its full name by running lxc-ls -f<\/span>.<\/span><\/p>\nlxc-attach -n infra1_neutron_agents_container-de4c0565<\/span><\/pre>\nOnce attached, we list the Linux namespaces using the following command:<\/p>\n
root@infra1-neutron-agents-container-de4c0565:~# ip netns list\r\nqdhcp-d5b08c40-3b9e-4d6e-872b-7e8ce1553703 (id: 5)\r\nqrouter-215981d1-32bc-41fd-a13a-27dbe7ecb63f (id: 4)\r\nqdhcp-579d7378-84ad-45d5-882d-e052bab9595e (id: 3)\r\nqdhcp-33ad9c28-5884-41e1-97c0-05886740b5c1 (id: 1)\r\nqdhcp-423b2b1b-5591-4861-baab-64e9fef84f47 (id: 2)<\/pre>\nBased upon our previous bridge name brq423b2b1b-55<\/span> we can correlate this to the name space – \u00a0qdhcp-423b2b1b-5591-4861-baab-64e9fef84f47<\/span>.<\/p>\nWith this namespace identifer we can run commands against the namespace, in order to help us with our troubleshooting. First, let us look at the IP address, this should be 192.168.1.2.<\/span><\/p>\nroot@infra1-neutron-agents-container-de4c0565:~# ip netns exec qdhcp-423b2b1b-5591-4861-baab-64e9fef84f47 ifconfig\r\nlo Link encap:Local Loopback\r\n inet addr:127.0.0.1 Mask:255.0.0.0\r\n inet6 addr: ::1\/128 Scope:Host\r\n UP LOOPBACK RUNNING MTU:65536 Metric:1\r\n RX packets:0 errors:0 dropped:0 overruns:0 frame:0\r\n TX packets:0 errors:0 dropped:0 overruns:0 carrier:0\r\n collisions:0 txqueuelen:1\r\n RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)\r\n\r\nns-e2e1c16d-6e Link encap:Ethernet HWaddr fa:16:3e:82:97:6e\r\n inet addr:192.168.1.2 Bcast:192.168.1.255 Mask:255.255.255.0\r\n inet6 addr: fe80::f816:3eff:fe82:976e\/64 Scope:Link\r\n UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1\r\n RX packets:160 errors:0 dropped:0 overruns:0 frame:0\r\n TX packets:97 errors:0 dropped:0 overruns:0 carrier:0\r\n collisions:0 txqueuelen:1000\r\n RX bytes:12228 (12.2 KB) TX bytes:7988 (7.9 KB)<\/pre>\nWell, the IP looks correct. Lets run another tcpdump, whilst running a curl on our guest.<\/span><\/p>\ntcpdump: verbose output suppressed, use -v or -vv for full protocol decode\r\nlistening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes\r\n22:14:13.529666 IP 192.168.1.50.49515 > 169.254.169.254.80: Flags [S], seq 851007280, win 14100, options [mss 1410,sackOK,TS val 78147174 ecr 0,nop,wscale 2], length 0\r\n22:14:13.529699 IP 169.254.169.254.80 > 192.168.1.50.49515: Flags [R.], seq 0, ack 851007281, win 0, length 0<\/pre>\nInteresting. So let us take a moment. The SYN from the 3WHS is making it all the way to the necessary Linux Bridge on the compute node. The SYN is then making it to the DHCP agent and its corresponding namespace, but still there is something sendin a RST and preventing the TCP connection to form. We at least know the path is good, but what next? Let us check that the metadata service proxy is actually listening on the required port.<\/p>\n
root@infra1-neutron-agents-container-de4c0565:~# ip netns exec qdhcp-423b2b1b-5591-4861-baab-64e9fef84f47 netstat -anp\r\nActive Internet connections (servers and established)\r\nProto Recv-Q Send-Q Local Address Foreign Address State PID\/Program name\r\ntcp 0 0 192.168.1.2:53 0.0.0.0:* LISTEN 1921\/dnsmasq\r\ntcp 0 0 169.254.169.254:53 0.0.0.0:* LISTEN 1921\/dnsmasq\r\ntcp6 0 0 fe80::f816:3eff:fe82:53 :::* LISTEN 1921\/dnsmasq\r\nudp 0 0 192.168.1.2:47830 10.0.3.1:53 ESTABLISHED 1642\/tcpdump\r\nudp 0 0 192.168.1.2:53 0.0.0.0:* 1921\/dnsmasq\r\nudp 0 0 169.254.169.254:53 0.0.0.0:* 1921\/dnsmasq\r\nudp 0 0 0.0.0.0:67 0.0.0.0:* 1921\/dnsmasq\r\nudp6 0 0 fe80::f816:3eff:fe82:53 :::* 1921\/<\/pre>\nWait, port 80 isnt listening. Let us restart the services, and recheck.<\/span><\/p>\nroot@infra1-neutron-agents-container-de4c0565:~# service neutron-dhcp-agent restart\r\nroot@infra1-neutron-agents-container-de4c0565:~# service neutron-metadata-agent restart<\/pre>\nroot@infra1-neutron-agents-container-de4c0565:~# ip netns exec qdhcp-423b2b1b-5591-4861-baab-64e9fef84f47 netstat -anp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID\/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1764\/python tcp 0 0 192.168.1.2:53 0.0.0.0:* LISTEN 1921\/dnsmasq tcp 0 0 169.254.169.254:53 0.0.0.0:* LISTEN 1921\/dnsmasq tcp6 0 0 fe80::f816:3eff:fe82:53 :::* LISTEN 1921\/dnsmasq udp 0 0 192.168.1.2:47830 10.0.3.1:53 ESTABLISHED 1642\/tcpdump udp 0 0 192.168.1.2:53 0.0.0.0:* 1921\/dnsmasq udp 0 0 169.254.169.254:53 0.0.0.0:* 1921\/dnsmasq udp 0 0 0.0.0.0:67 0.0.0.0:* 1921\/dnsmasq udp6 0 0 fe80::f816:3eff:fe82:53 :::* 1921\/dnsmasq<\/p>\n
Now port 80 is back up, we can now see if the metaservice is accessable from our guest.<\/p>\n