PageSourceSearch

https://cilium.io/component---src-templates-blog-post-jsx-content-…f-firewall-index-md-d80539604b78f1656c56.js

js cilium.io collected 2026-09-24 08:26:22 UTC 39,722 bytes, 2 lines download raw bytes

1"use strict";(self.webpackChunkcilium_io=self.webpackChunkcilium_io||[]).push([[1983],{8012:function(e,n,a){a.r(n),a.d(n,{Head:function(){return d},default:function(){return f}});var t=a(8453),s=a(6540);function o(e){const n=Object.assign({span:"span",p:"p",a:"a",h2:"h2",h1:"h1",strong:"strong",ul:"ul",li:"li"},(0,t.RP)(),e.components);return s.createElement(s.Fragment,null,s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1008px; "\n    >\n      <a\n    class="gatsby-resp-image-link"\n    href="/static/8c1586e52b50902be2fb0876af7d24d9/437a1/ogimage.png"\n    style="display: block"\n    target="_blank"\n    rel="noopener"\n  >\n    <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 38.49206349206349%; position: relative; bottom: 0; left: 0; background-image: url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB/klEQVR42j1S6W4SURSeN9JETatWCl3QVkMXB8o2DJTCSIt0kUIRbU3VaDdTSgsIDGtZBrqEmLZxSxQ1Li/1ee6N8cfJ3Dvn5tvOEfrsGdyeKcD39Bj2cANLr8/wpvQdYqgGU6CCufUOnBENrmgLMquVFqbjRwi9fEf/m4hsncO6VMdksAqGJehdWQxNqxhw52CarRBoE+L8IbzxY0S2L7B+8BnhjTOs7n3EWvITojsXMM/XYFmsY2yuAmX1BFN01jkzYFjCdWsK7lgLYwTGGn2ODK6K+xhVSrj3oASjV+VE7D7oyfPzDVsalyf2MEw9yyKBL9S48hF/EYJBznEgieyIxHxpPIGtwldsF7pYJjvhzXPk2n+42ieJD4jvvkeq8QsGOYs7vsJ/MBaL3pWDwHLrl7Kcnam5cj8J/9opNtUuEpUf2KVKHv7Eq+wXpBu/sZHvYqf4DUP/3vvJ8jhZNwXKGKboBBYoGwprmomNRWDwlDE4U0e/u4IBb41/9VS9dhU6uQyjokEn5XGL4pFIGVPnibUx4iPLN2kyUlTjLDZSy4bTa01DXKhDjh3BsazBEdZge9Tkk3ZGWvRGRc9UCka+HScc1PO4zUUJOuktl8vqLgU/qhRxzbzPCYIvOgg8O0XweYeDzdIKyStt7qLHcsA3QaF4Jh5WMRmqcjF/AfCthZjdnVP5AAAAAElFTkSuQmCC\'); background-size: cover; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/8c1586e52b50902be2fb0876af7d24d9/2ff5b/ogimage.webp 252w,\n/static/8c1586e52b50902be2fb0876af7d24d9/4d583/ogimage.webp 504w,\n/static/8c1586e52b50902be2fb0876af7d24d9/905a7/ogimage.webp 1008w,\n/static/8c1586e52b50902be2fb0876af7d24d9/bb9f8/ogimage.webp 1512w,\n/static/8c1586e52b50902be2fb0876af7d24d9/a8642/ogimage.webp 1536w"\n              sizes="(max-width: 1008px) 100vw, 1008px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/8c1586e52b50902be2fb0876af7d24d9/019e0/ogimage.png 252w,\n/static/8c1586e52b50902be2fb0876af7d24d9/0dcb2/ogimage.png 504w,\n/static/8c1586e52b50902be2fb0876af7d24d9/832a9/ogimage.png 1008w,\n/static/8c1586e52b50902be2fb0876af7d24d9/19357/ogimage.png 1512w,\n/static/8c1586e52b50902be2fb0876af7d24d9/437a1/ogimage.png 1536w"\n            sizes="(max-width: 1008px) 100vw, 1008px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/8c1586e52b50902be2fb0876af7d24d9/832a9/ogimage.png"\n            alt="Facebook Infrastructure Logo"\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n  </a>\n    </span>'}}),"\n",s.createElement(n.p,null,"We have covered Facebook's BPF-based load balancer with DDoS protection in\na previous blog post: ",s.createElement(n.a,{href:"/blog/2018/04/17/why-is-the-kernel-community-replacing-iptables"},"Why is the kernel community replacing iptables with BPF?"),".\nThis post provides further details on Facebook's BPF use by covering Anant\nDeepak's talk at the ",s.createElement(n.a,{href:"http://vger.kernel.org/lpc-networking.html"},"BPF/networking microconference")," on Facebook's BPF-based\nedge firewall running in production."),"\n",s.createElement(n.p,null,"The same conference also featured many other BPF related talks which we will\ncover in follow-up blog posts. In particular interesting will be Nikita V.\nShirokov's (Facebook) talk ",s.createElement(n.a,{href:"http://vger.kernel.org/lpc_net2018_talks/LPC_XDP_Shirokov_v2.pdf"},"XDP: 1.5 years in production. Evolution and\nlessons\nlearned"),"\nwhere Nikita shows the impressive difference between IPVS and BPF under heavy\nload as well as Vlad Dumitrescu from Google talking about ",s.createElement(n.a,{href:"http://vger.kernel.org/lpc_bpf2018_talks/lpc-bpf-2018-shaping.pdf"},"Scaling Linux\nTraffic Shaping with\nBPF")," where\nVlad and others share their experience deploying BPF to production solving\nscalable traffic shaping."),"\n",s.createElement("a",{id:"problems-of-the-existing-iptables-firewall"}),"\n",s.createElement(n.h2,null,"Problems of the existing iptables firewall"),"\n",s.createElement(n.p,null,"Anant started his ",s.createElement(n.a,{href:"http://vger.kernel.org/lpc_net2018_talks/ebpf-firewall-LPC.pdf"},"talk"),"\nproviding the background on the need to replace the existing iptables firewall\nwith BPF. At the root of the problem lies the sequential nature of the iptables\npolicy engine. To demonstrate this, Anant showed a 
1simplified version of the\ncode used to traverse a list of rules:"),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="c"><pre class="language-c"><code class="language-c"><span class="token comment">// net/ipv6/netfilter/ip6_tables.c</span>\n<span class="token keyword">unsigned</span> <span class="token keyword">int</span> <span class="token function">ip6t_do_table</span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span>\n<span class="token punctuation">{</span>\n    e <span class="token operator">=</span> <span class="token function">get_entry</span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token keyword">do</span> <span class="token punctuation">{</span>\n        <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>\n        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">ip6_packet_match</span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n            e <span class="token operator">=</span> <span class="token function">ip6t_next_entry</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>\n            <span class="token keyword">continue</span>\n        <span class="token punctuation">}</span>\n        <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>\n    <span class="token punctuation">}</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span></code></pre></div>'}}),"\n",s.createElement(n.p,null,"Logic such as this was common 20 years ago when iptables was created. A primary\nreason for this model was that most hardware-based firewalls were configured\nusing sequential list of rules. However, while hardware-based firewalls\nprimarily used ",s.createElement(n.a,{href:"https://en.wikipedia.org/wiki/Content-addressable_memory#Ternary_CAMs"},"TCAM")," for its parallel search capability and constant\nprocessing speed, the iptables implementation in software has always been\nsuffering from linearly increasing CPU utilization as more rules are being\nadded to a table. The performance suffers in particular if packets are\nfrequently hitting rules in the lower parts of the table."),"\n",s.createElement(n.p,null,"To illustrate this, Anant showed and explained the iptables ruleset that\npreviously applied to all network traffic entering any of the datacenters. The\npurpose of the rules is to filter out unwanted traffic to protect the\nload balancers from DDoS and other attacks. As you can tell based on the\nruleset, even though the ruleset is quite optimized to allow matching the\nmajority"),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1008px; "\n    >\n      <a\n    class="gatsby-resp-image-link"\n    href="/static/91368a31aad0370dffc6df4886b86e21/c4844/iptables_ruleset.png"\n    style="display: block"\n    target="_blank"\n    rel="noopener"\n  >\n    <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 43.25396825396825%; position: relative; bottom: 0; left: 0; background-image: url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB7UlEQVR42j2S25KiMBRF+f9P6qnumZoZ2yq7VVTwCoIIRkkggBfaW68JPMzDrnXO3sl5yIm1VzVpfkUVd/bZV8usfCD1DWGyaFci5IW8elKcaKXyM9Nlgj2NcJcC241wDMOkwApEzXp3IVFPNvsvYnknyZ5sDUPTh/srUXprc5HT6qDODKcJnUFI3xW8DwK6w4jlpsSStUZ9lRT3E7Iu0IbVd90yvWh2lWSr923W+BU1qirxxJaliFp5h5i4UuZcipXUOw63FPlQiC/xv07vkuSyIyhCdrVAPTPyb02ORh5znGjOhz/g0x/SX9t4OiTUMVal15yrDddLglYrROyQihmF8ijzNVm6NL6H3M+5mcGPq6AsJP5qzHzaYznvM3N7xBsHeQiwpqpkkZ/wq5qxUNiJxCsvRmdcqRkZz00bSoLTtVWij3QXG14dn1+zgLeJR3ctmOxyrMlWMxNHVmaTdqgYbTJT1ywOZ5pssJZt7pmN++YXeFmzuIruJOC1v+T3yAw0fJ/FTMx9y5sIgmlKtMhYO/uW8UqzmSuazP0M8Y2feEWreFWYZ8npd6Z0XoZ030Z0X0cM/ixYjROs2/CTm93nObFp6ud4yLcz4mF4NX2ju8kbD3cMjs0xigj+dvB/vBD+fEN/fFD2eujRmH9TO5SMOyjMPwAAAABJRU5ErkJggg==\'); background-size: cover; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/91368a31aad0370dffc6df4886b86e21/2ff5b/iptables_ruleset.webp 252w,\n/static/91368a31aad0370dffc6df4886b86e21/4d583/iptables_ruleset.webp 504w,\n/static/91368a31aad0370dffc6df4886b86e21/905a7/iptables_ruleset.webp 1008w,\n/static/91368a31aad0370dffc6df4886b86e21/bb9f8/iptables_ruleset.webp 1512w,\n/static/91368a31aad0370dffc6df4886b86e21/83a93/iptables_ruleset.webp 2016w,\n/static/91368a31aad0370dffc6df4886b86e21/8b29b/i
1ptables_ruleset.webp 2318w"\n              sizes="(max-width: 1008px) 100vw, 1008px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/91368a31aad0370dffc6df4886b86e21/019e0/iptables_ruleset.png 252w,\n/static/91368a31aad0370dffc6df4886b86e21/0dcb2/iptables_ruleset.png 504w,\n/static/91368a31aad0370dffc6df4886b86e21/832a9/iptables_ruleset.png 1008w,\n/static/91368a31aad0370dffc6df4886b86e21/19357/iptables_ruleset.png 1512w,\n/static/91368a31aad0370dffc6df4886b86e21/29ed2/iptables_ruleset.png 2016w,\n/static/91368a31aad0370dffc6df4886b86e21/c4844/iptables_ruleset.png 2318w"\n            sizes="(max-width: 1008px) 100vw, 1008px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/91368a31aad0370dffc6df4886b86e21/832a9/iptables_ruleset.png"\n            alt="Facebook iptables ruleset"\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n  </a>\n    </span>'}}),"\n",s.createElement(n.p,null,"Why is there no rule matching on the connection tracking state and allowing all\nestablished connections as seen in common iptables rules sets? The overhead of\nthe iptables/netfilter connection tracker would simply bring any machine to its\nknees when being hit with the common Facebook traffic pattern."),"\n",s.createElement("a",{id:"benef
1its-of-a-bpf-based-firewall"}),"\n",s.createElement(n.h1,null,"Benefits of a BPF-based firewall"),"\n",s.createElement(n.p,null,"What exactly can BPF do better? The slide that Anant presented listed the\nfollowing overview:"),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1008px; "\n    >\n      <a\n    class="gatsby-resp-image-link"\n    href="/static/38312f64f4b4e21b16edf1abec651c79/2e49e/bpf_benefits.png"\n    style="display: block"\n    target="_blank"\n    rel="noopener"\n  >\n    <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 47.61904761904761%; position: relative; bottom: 0; left: 0; background-image: url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABOElEQVR42o1SW3KDMAz0/U+XBgLYGPM2NlByBFUrHtNOJ00/diR57PVqJaVLR6Vtqap7CnGlOH8e4PxH/T+ofpzpkVvKCkvWtVRoR7muyFacGyfoh0DL+qR52d4TdkOkNCuFcCeuBDgDHCvvx0CjnyWGN6pVYeqLAMqQnxE2QKkuazJVI+ejj38qVVPcCKTJQwsp/ERuXXc9PttFPB++UqoGvzIR2i1FFTxLUs2khpU138g2jk+pkb/yVBTmPAiou91zehx+fiSFqDS2IcPEiJo/M9x+xee403b+F6mCsjsrwgW0OIVF2gGQ+2mmYYwSAbkTFxnSFNZL6Ums2j7QjdWgVeykKGEVGAAibDBHjS1Anh0RZ/DfT4t8LoT+GAoeY6KyPgxchhWo08wITo/PNdsJdxHYX1jwBVzN2bQzZrwuAAAAAElFTkSuQmCC\'); background-size: cover; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/38312f64f4b4e21b16edf1abec651c79/2ff5b/bpf_benefits.webp 252w,\n/static/38312f64f4b4e21b16edf1abec651c79/4d583/bpf_benefits.webp 504w,\n/static/38312f64f4b4e21b16edf1abec651c79/905a7/bpf_benefits.webp 1008w,\n/static/38312f64f4b4e21b16edf1abec651c79/bb9f8/bpf_benefits.webp 1512w,\n/static/38312f64f4b4e21b16edf1abec651c79/83a93/bpf_benefits.webp 2016w,\n/static/38312f64f4b4e21b16edf1abec651c79/c6dfc/bpf_benefits.webp 2070w"\n              sizes="(max-width: 1008px) 100vw, 1008px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/38312f64f4b4e21b16edf1abec651c79/019e0/bpf_benefits.png 252w,\n/static/38312f64f4b4e21b16edf1abec651c79/0dcb2/bpf_benefits.png 504w,\n/static/38312f64f4b4e21b16edf1abec651c79/832a9/bpf_benefits.png 1008w,\n/static/38312f64f4b4e21b16edf1abec651c79/19357/bpf_benefits.png 1512w,\n/static/38312f64f4b4e21b16edf1abec651c79/29ed2/bpf_benefits.png 2016w,\n/static/38312f64f4b4e21b16edf1abec651c79/2e49e/bpf_benefits.png 2070w"\n            sizes="(max-width: 1008px) 100vw, 1008px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/38312f64f4b4e21b16edf1abec651c79/832a9/bpf_benefits.png"\n            alt="BPF Benefits"\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n  </a>\n    </span>'}}),"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Performance:")," The performance aspect is the most important. By using\nefficient BPF map data structures, the sequential lookups can be avoided and\nthe performance of the firewall is increased significantly. But even more\nimportantly, a DoS attack on closed ports which previously hit the default deny rule at the end of the rules set is no longer effective to impose an unnecessary load on the infrastructure."),"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"XDP:")," XDP is a special BPF mode which enables BPF programs to take control\nover network packets at the network driver level. This brings additional\nperformance benefits due to decreased overhead and more importantly allows to\nrun the firewall right in front of the existing BPF-based load balancer. The\nchaining is done using BPF tail calls which is a function call like construct\nwith excellent performance attributes. As requirements change, Facebook\nengineers can write additional programs to provide rate limiting, additional\nfiltering, or other custom logic and simply hook the programs into the chain.\nThe flexibility of BPF allows creating matching logic at arbitrary offsets in\nthe packet and provides powerful logic to handle any upcoming DoS scenario or\nfiltering requirement."),"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Manageability:")," The performance of BPF is outstanding and often an initial\nmotivation to get involved in BPF but infrastru
1cture engineers ultimately fall\nin love with BPF due to its flexibility, programmability, and manageability.\nBits in network packet headers can be arbitrarily interpreted and re-purposed,\npolicy can be decoupled from the network topology by creating a logical mapping\nvia packet attributes, visibility at any network layer is a matter of writing\nthe respective program. An extensive userspace API allows interacting with\nprograms to export statistics, update maps and atomically replace BPF programs."),"\n",s.createElement("a",{id:"bpf-program-details"}),"\n",s.createElement(n.h1,null,"BPF Program Details"),"\n",s.createElement(n.p,null,"The illustration below shows a simplified view of the BPF program that\nimplements the equivalent of the iptables rule set as shown before. A single\nBPF map lookup per tuple using an LPM (Longest Prefix Match) table maps the\nnetwork topology to a logical policy which is then interpreted. The policy\nlogic itself is not that different from before, it still allows to use a list\nof logical conditions to implement precedence. Unlike the individual iptables\nrule matching function which translates into hundreds or thousands of CPU\ninstructions with a series of memory accesses. The BPF implementation\ntranslates into a small number of CPU instructions with the logic implementing\nthe policy all using register-based accesses."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1008px; "\n    >\n      <a\n    class="gatsby-resp-image-link"\n    href="/static/da97e42aefbae8e4b4426104595fc415/29524/bpf_prog_struct.png"\n    style="display: block"\n    target="_blank"\n    rel="noopener"\n  >\n    <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 42.06349206349206%; position: relative; bottom: 0; left: 0; background-image: url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABwklEQVR42lWR6WobMRhF5/3foySkpC00P0oLjZ2lK6RJmtqezdasmkWafbwkJaeKA4X8OFx9AqHv3mv5YcNi1eEELbZoEHJDmO2M7oiLHat0zTIscEWJJzKSJCFKFe9Pbd5NfE7OV5xMbD5faebmvRXplrTfkA1bckMx7pBmlt2arN9SjlvCICAKAzzPw3Vtcj3w9rLi9fnA0VnD8VnJq8nA91mHpfoYPUZU6xg1hPtzs03p7nO6B8MuJ4lDwjDC9XxWK0Hd1Mg0YmwVZZ4QiiW1kjSVxhq0T1/ajNpjUA6b2ufvEPG4SXhcPxGD+aCpFVnZUKiaNFeI2Ng31n2RsnAEIspJpcJyyopFYSjrvTqqwa1aRL9+gdQ1uszRqqQ0WhSSXMp9FGkSm2wjilxi3eUdv7KW3+XAbdHzR6+Z11vs9v6ZZofTPbDKKj5euHz6FvDh0pQxdfl6V3HlDlx7Az/tnh/zFmsxK3DmZrOFxp4plq7Zbjkg/P4/wZOGFcdfWg5OFYeTioNpx9HFwMGk4c255nDamnnEKq5n1LcLqidu5vQzk+Xcf8Fo7so4JZYxgRCmoMCUIfcWo+B5TqKQIkv5ByOYSMt7OaLfAAAAAElFTkSuQmCC\'); background-size: cover; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/da97e42aefbae8e4b4426104595fc415/2ff5b/bpf_prog_struct.webp 252w,\n/static/da97e42aefbae8e4b4426104595fc415/4d583/bpf_prog_struct.webp 504w,\n/static/da97e42aefbae8e4b4426104595fc415/905a7/bpf_prog_struct.webp 1008w,\n/static/da97e42aefbae8e4b4426104595fc415/bb9f8/bpf_prog_struct.webp 1512w,\n/static/da97e42aefbae8e4b4426104595fc415/83a93/bpf_prog_struct.webp 2016w,\n/static/da97e42aefbae8e4b4426104595fc415/f0afb/bpf_prog_struct.webp 2272w"\n              sizes="(max-width: 1008px) 100vw, 1008px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/da97e42aefbae8e4b4426104595fc415/019e0/bpf_prog_struct.png 252w,\n/static/da97e42aefbae8e4b4426104595fc415/0dcb2/bpf_prog_struct.png 504w,\n/static/da97e42aefbae8e4b4426104595fc415/832a9/bpf_prog_struct.png 1008w,\n/static/da97e42aefbae8e4b4426104595fc415/19357/bpf_prog_struct.png 1512w,\n/static/da97e42aefbae8e4b4426104595fc415/29ed2/bpf_prog_struct.png 2016w,\n/static/da97e42aefbae8e4b4426104595fc415/29524/bpf_prog_struct.png 2272w"\n            sizes="(max-width: 1008px) 100vw, 1008px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/da97e42aefbae8e4b4426104595fc415/832a9/bpf_prog_struct.png"\n            alt="BPF firewall program example"\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n  </a>\n    </span>'}}),"\n",s.createElement(n.h1,null,"Performance"),"\n",s.createElement(n.p,null,"Facebook often doesn't publish absolute numbers in terms of performance so we\ndon't see the exact absolute CPU utilization but the comparison between\niptables (orange) and BPF (blue) clearly indicates how the utilization stays\nconstant for the BPF firewall while the iptables firewall suffers from a peak\nof increased CPU utilization which translates to a successful DoS attack and\nunnecessary load on the infrastru
1cture."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 932px; "\n    >\n      <a\n    class="gatsby-resp-image-link"\n    href="/static/fc36b0a3af98ffe5dcc35ef6b5ee9934/9ef50/performance_overview.png"\n    style="display: block"\n    target="_blank"\n    rel="noopener"\n  >\n    <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 66.26984126984128%; position: relative; bottom: 0; left: 0; background-image: url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAlUlEQVR42s2SCwvCMAyE9/9/rvS1prl4TceEqei0goGj7y8XmsVeBUDpg224jrE854wHaKuh5tt6k6qeA+5BoEnpKb5zuJfb6kSgtgHswjSgjLLxvw5/UvJ0h3LX3B8DQSA2MLx54OPpxu6XZS1kCqX86OxzCMEcW+VZT/Q2kA4qgbkUizFaSdFSuFgMgWsqJXd5BF4BxEIJlaABTVgAAAAASUVORK5CYII=\'); background-size: cover; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/fc36b0a3af98ffe5dcc35ef6b5ee9934/2ff5b/performance_overview.webp 252w,\n/static/fc36b0a3af98ffe5dcc35ef6b5ee9934/4d583/performance_overview.webp 504w,\n/static/fc36b0a3af98ffe5dcc35ef6b5ee9934/1cbe2/performance_overview.webp 932w"\n              sizes="(max-width: 932px) 100vw, 932px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/fc36b0a3af98ffe5dcc35ef6b5ee9934/019e0/performance_overview.png 252w,\n/static/fc36b0a3af98ffe5dcc35ef6b5ee9934/0dcb2/performance_overview.png 504w,\n/static/fc36b0a3af98ffe5dcc35ef6b5ee9934/9ef50/performance_overview.png 932w"\n            sizes="(max-width: 932px) 100vw, 932px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/fc36b0a3af98ffe5dcc35ef6b5ee9934/9ef50/performance_overview.png"\n            alt="Performance"\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n  </a>\n    </span>'}}),"\n",s.createElement(n.ul,null,"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,"iptables has a linearly increasing CPU utilization as packets hit lower rules"),"\n",s.createElement(n.ul,null,"\n",s.createElement(n.li,null,"Best when packets match earlier rules"),"\n",s.createElement(n.li,null,"Worst for default policy (match attempted for each rule)"),"\n"),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,"The BPF firewall performance remains practically constant irrespective of\nthe rule being matched or default drop"),"\n",s.createElement(n.ul,null,"\n",s.createElement(n.li,null,"Packet tuple lookup is efficient with only 1 BPF map per tuple"),"\n",s.createElement(n.li,null,"Location of matching rule now only matters to the extent of few branching\ninstructions"),"\n"),"\n"),"\n"),"\n",s.createElement(n.h1,null,"Next Steps"),"\n",s.createElement(n.p,null,"The firewall described in the talk is specific to Facebook's edge use case\nwhich has the most specific performance requirements. There are many other use\ncases for firewalls where performance is still important but reconfigurability\nand flexibility start becoming more important as well. For this reason, Anant\nalso provided insights into some ongoing projects:"),"\n",s.createElement("a",{id:"iptables-style-bpf-firewall-prototype"}),"\n",s.createElement(n.h2,null,"IPtables-style BPF firewall Prototype"),"\n",s.createElement(n.p,null,"The presented BPF program can be generalized a bit to make it more flexible.\nFacebook engineers have written a prototype which can translate a set of\nlimited iptables rules into a BPF program and map. The per-packet algorithm is\nsimilar to the program discussed in the first part of the talk with a single\nBPF map lookup per tuple. Instead of the verdict, the value of the BPF map\ncarries a bit array which describes the verdict based on the rule position."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="c"><pre class="language-c"><code class="language-c"><span class="token comment">// Parse the packet and lookup against maps for each attribute</span>\n<span class="token comment">// *_res are the results of the lookup</span>\nip4_src_addr_res <span class="token operator">=</span> <span class="token function">lookup_ipv4_src_addr</span><span class="token punctuation">(</span>iph<span class="token operator">-></span>saddr<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n<span class="token comment">// ..collect _res for all other tuples</span>\n<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">pragma</span> <span class="token expression">clang loop <span class="token function">unroll</span><span class="token punctuation">(</span>
1full<span class="token punctuation">)</span></span></span>\n<span class="token keyword">for</span> <span class="token punctuation">(</span>rule_word <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> rule_word <span class="token operator">&lt;</span> RULE_IDS_MAX_WORDS<span class="token punctuation">;</span> rule_word<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  u64 rule_id <span class="token operator">=</span> ip4_src_addr_res<span class="token operator">-></span>rule_ids<span class="token punctuation">[</span>rule_word<span class="token punctuation">]</span><span class="token punctuation">;</span>\n      rule_id <span class="token operator">&amp;=</span> ip4_src_lpm_res<span class="token operator">-></span>rule_ids<span class="token punctuation">[</span>rule_word<span class="token punctuation">]</span><span class="token punctuation">;</span>\n      rule_id <span class="token operator">&amp;=</span> ip4_dst_addr_res<span class="token operator">-></span>rule_ids<span class="token punctuation">[</span>rule_word<span class="token punctuation">]</span><span class="token punctuation">;</span>\n      rule_id <span class="token operator">&amp;=</span> ip4_dst_lpm_res<span class="token operator">-></span>rule_ids<span class="token punctuation">[</span>rule_word<span class="token punctuation">]</span><span class="token punctuation">;</span>\n      rule_id <span class="token operator">&amp;=</span> ip6_src_addr_res<span class="token operator">-></span>rule_ids<span class="token punctuation">[</span>rule_word<span class="token punctuation">]</span><span class="token punctuation">;</span>\n      rule_id <span class="token operator">&amp;=</span> ip6_dst_addr_res<span class="token operator">-></span>rule_ids<span class="token punctuation">[</span>rule_word<span class="token punctuation">]</span><span class="token punctuation">;</span>\n      rule_id <span class="token operator">&amp;=</span> ip6_src_lpm_res<span class="token operator">-></span>rule_ids<span class="token punctuation">[</span>rule_word<span class="token punctuation">]</span><span class="token punctuation">;</span>\n      rule_id <span class="token operator">&amp;=</span> ip6_dst_lpm_res<span class="token operator">-></span>rule_ids<span class="token punctuation">[</span>rule_word<span class="token punctuation">]</span><span class="token punctuation">;</span>\n      rule_id <span class="token operator">&amp;=</span> src_port_res<span class="token operator">-></span>rule_ids<span class="token punctuation">[</span>rule_word<span class="token punctuation">]</span><span class="token punctuation">;</span>\n      rule_id <span class="token operator">&amp;=</span> dst_port_res<span class="token operator">-></span>rule_ids<span class="token punctuation">[</span>rule_word<span class="token punctuation">]</span><span class="token punctuation">;</span>\n      rule_id <span class="token operator">&amp;=</span> ip_proto_res<span class="token operator">-></span>rule_ids<span class="token punctuation">[</span>rule_word<span class="token punctuation">]</span><span class="token punctuation">;</span>\n      rule_id <span class="token operator">&amp;=</span> tcp_flag_res<span class="token operator">-></span>rule_ids<span class="token punctuation">[</span>rule_word<span class="token punctuation">]</span><span class="token punctuation">;</span>\n\n  <span class="token keyword">if</span> <span class="token punctuation">(</span>rule_id<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    <span class="token comment">// find first bit set (MSB)</span>\n    <span class="token keyword">int</span> rule_num <span class="token operator">=</span> <span class="token punctuation">(</span>rule_word <span class="token operator">*</span> <span class="token number">64</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token function">get_msb_set</span><span class="token punctuation">(</span>rule_id<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n    <span class="token comment">// Take action</span>\n    <span class="token keyword">int</span> action <span class="token operator">=</span> <span class="token function">lookup_action</span><span class="token punctuation">(</span>rule_num<span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token keyword">if</span> <span class="token punctuation">(</span>action <span class="token operator">==</span> BPFILTER_ACTION_PASS<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      XDP_PASS<span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n\n    <span class="token keyword">if</span> <span class="token punctuation">(</span>action <span class="token operator">==</span> BPFILTER_ACTION_DENY<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      XDP_DROP<span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n  <span class="token punctuation">}</span>\n<span class="token punctuation">}</span></code></pre></div>'}}),"\n",s.createElement(n.p,null,"The full details can be found in the ",s.createElement(n.a,{href:"http://vger.kernel.org/lpc_net2018_talks/ebpf-firewall-LPC.pdf"},"slides")," and ",s.createElement(n.a,{href:"http://vger.kernel.org/lpc_net2018_talks/ebpf-firewall-paper-LPC.pdf"},"paper"),". As of now, the prototype still has some restrictions such as no support for REJECT rules."),"\n",s.createElement(n.h2,null,"bpfilter"),"\n",s.createElement(n.p,null,"As known publicly for a 
1while, the kernel community is working on replacing the\nin-kernel portion of iptables with BPF. Anant provided an update on this\nproject called ",s.createElement(n.a,{href:"https://lwn.net/Articles/747551"},"bpfilter"),". Unlike the prototype described in the previous chapter\nwhich works by having the user pipe ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">iptables-save</code>'}})," output into a python\nprogram that generates a BPF program. The bpfilter program handles the\nconversion from iptables to BPF as part of a kernel interface to provide\nseamless backward compatibility. The goal is to allow users to continue using\niptables as-is while providing a more performant implementation."),"\n",s.createElement(n.h1,null,"Summary"),"\n",s.createElement(n.p,null,"Anant provided great details on Facebook's BPF use to build a highly efficient\nand flexible firewall that complements the existing BPF-based load balancer.\nThe new firewall demonstrates constant CPU utilization regardless of the type\nof traffic that is being processed and has become immune against DoS attacks.\nThe main reason listed for the migration away from the outdated iptables model\nis the sequential matching semantics of iptables and the superior performance\nand manageability of the BPF subsystem."),"\n",s.createElement(n.p,null,"A recording of the talk should become available in a couple of weeks on the\n",s.createElement(n.a,{href:"http://vger.kernel.org/lpc-networking.html"},"microconference page"),"."),"\n",s.createElement(n.p,null,"This post covered one of the many exciting talks on the topic of BPF, both the\nBPF and Networking microconference where overflowing with BPF related talks. To\npick just a few:"),"\n",s.createElement(n.ul,null,"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"http://vger.kernel.org/lpc_bpf2018_talks/lpc-bpf-2018-shaping.pdf"},"Scaling Linux Traffic Shaping with BPF, Vlad Dumitrescu (Google) et al")),"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"http://vger.kernel.org/lpc_net2018_talks/LPC_XDP_Shirokov_v2.pdf"},"XDP: 1.5 years in production. Evolution and lessons learned, Nikita V. Shirokov (Facebook)")),"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"http://vger.kernel.org/lpc_net2018_talks/ktls_bpf.pdf"},"Combining kTLS and BPF for Introspection and Policy Enforcement, Daniel Borkmann (Cilium) et al.")),"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"http://vger.kernel.org/lpc_bpf2018_talks/bounded-loops.pdf"},"BPF control flow, supporting loops and other patterns, John Fastabend (Cilium)")),"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"http://vger.kernel.org/lpc_bpf2018_talks/LPC2018-TokenBucket_v4.pdf"},"Traffic policing in eBPF: applying token bucket algorithm, Julia Kartseva (Facebook)")),"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"http://vger.kernel.org/lpc_bpf2018_talks/bpf_compile_once.pdf"},"Compile once, run everywhere, Yonghong Song and Alexei Starovoitov (Facebook)")),"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"http://vger.kernel.org/lpc_bpf2018_talks/bpf_global_data_and_static_keys.pdf"},"ELF relocation for static data in BPF, Joe Stringer (Cilium) and Daniel Borkmann (Cilium)")),"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"http://vger.kernel.org/lpc_net2018_talks/presentation-lpc2018-xdp-future.pdf"},"XDP - challenges and future work, Jesper Brouer (Red Hat), Toke Høiland-Jørgensen (Karlstad University)")),"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"http://vger.kernel.org/lpc_net2018_talks/ovs-ebpf-lpc18-presentation.pdf"},"Bringing the Power of eBPF to Open vSwitch, William Tu (VMware) et al.")),"\n"),"\n",s.createElement(n.p,null,"You can find the full list of talks including slides and papers on the\n",s.createElement(n.a,{href:"http://vger.kernel.org/lpc-bpf.html"},"BPF")," and\n",s.createElement(n.a,{href:"http://vger.kernel.org/lpc-networking.html"},"Networking")," microconference\nwebsites. If you want to learn more about BPF, dive into the ",s.createElement(n.a,{href:"http://docs.cilium.io/en/stable/bpf/"},"BPF and XDP\nReference Guide"),"."),"\n",s.createElement(n.p,null,"If you are interested in leveraging BPF and XDP for networking, policy and load\nbalancing in the context of containers, Kubernetes and microservices then have\na look at ",s.createElement(n.a,{href:"https://github.com/cilium/cilium"},"Cilium"),"."),"\n",s.createElement(n.h2,null,"References"),"\n",s.createElement(n.ul,null,"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"http://docs.cilium.io/en/stable/bpf/"},"BPF and XDP Reference Guide")),"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"https://code.fb.com/open-source/linux/"},"Facebook open-sources new suite of Linux kernel components and tools")),"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"https://lwn.net/Articles/747551"},"bpfilter LWN article")),"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"https://github.com/facebookincubator/katran"},"katran - Facebook loadbalancer repository")),"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"https://netdevconf.org/2.1/session.html?zhou"},"droplet - BPF-based DDoS counter measures from Facebook")),"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"https://dl.acm.org/citation.cfm?id=3234228"},"SIGCOMM 2018 - Accelerating Linux Security with eBPF iptables")),"\n",s.createElement(n.li,null,s.createElement(n.a,{href:"https://cilium.io/blog/2018/04/17/why-is-the-kernel-community-replacing-iptables/"},"Why is the kernel community replacing iptables with BPF?")),"\n"))}var l=function(e){void 0===e&&(e={});const{wrapper:n}=Object.assign({},(0,t.RP)(),e.components);return n?s.createElement(n,e,s.createElement(o,e)):o(e)}
1,i=a(8125),p=a(5805),r=a(8838),c=a(2744);const u=e=>{const{data:{mdx:n},children:a}=e,{frontmatter:{path:t,title:o,date:l,tags:r,ogSummary:u}}=n;return s.createElement(c.A,{headerWithSearch:!0},s.createElement(i.A,{path:t,content:a,date:l,title:o,tags:r,summary:u}),s.createElement(p.A,{className:"my-10 md:my-20 lg:my-28"}))},d=e=>{var n,a;let{data:{mdx:t,site:o},location:{pathname:l}}=e;const{frontmatter:{title:i,ogImage:p,ogSummary:c,dateIso:u,tags:d,author:f}}=t,{siteUrl:m}=o.siteMetadata,b=`${c.slice(0,133)}...`,g=`${m}${l}`,h=null!=p&&null!==(n=p.childImageSharp)&&void 0!==n&&null!==(a=n.resize)&&void 0!==a&&a.src?`${m}${p.childImageSharp.resize.src}`:null,k={title:i,description:b,image:p||null,slug:l},w={"@context":"https://schema.org","@type":"BlogPosting",headline:i,description:b,url:g,datePublished:u,dateModified:u,author:f?{"@type":"Person",name:f}:{"@type":"Organization",name:"Cilium",url:m},publisher:{"@type":"Organization",name:"Cilium",url:m,logo:{"@type":"ImageObject",url:`${m}/images/social-preview.jpg`}},...h&&{image:{"@type":"ImageObject",url:h,width:1200,height:630}},...(null==d?void 0:d.length)>0&&{keywords:d.join(", ")}};return s.createElement(r.A,{data:k,type:"article",datePublished:u,jsonLd:w})};function f(e){return s.createElement(u,e,s.createElement(l,e))}}}]);
2//# sourceMappingURL=component---src-templates-blog-post-jsx-content-file-path-src-posts-2018-11-20-fb-bpf-firewall-index-md-d80539604b78f1656c56.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.