-
Notifications
You must be signed in to change notification settings - Fork 0
/
linux_network_interface_naming.html
264 lines (247 loc) · 15.1 KB
/
linux_network_interface_naming.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="canonical" href="http://tdt.rocks/linux_network_interface_naming.html" />
<title> TDT — Linux network interface naming
</title>
<link type="application/atom+xml" rel="alternate" href="/feed/atom.xml" title="TDT Atom Feed">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat" type="text/css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" href="http://tdt.rocks/theme/css/pygments.css">
<link rel="stylesheet" href="http://tdt.rocks/theme/css/style.css">
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-71190709-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-71190709-1');
</script>
<meta name="author" content="James Nzomo">
<meta name="description" content="About how net-if's get their names - from kernel only naming to biosdevname and systemd-udev schemes.">
<meta name="tags" contents="linux, systemd, network interfaces, ">
</head>
<body>
<header class="header">
<div class="container">
<div class="header-inner">
<!-- <h3 class="header-text">Thoughts & Deeds on Tech</h3> -->
<ul class="header-menu list-inline text-right">
<li><a class="nodec" href="http://tdt.rocks/categories.html">Categories</a></li>
<li class="muted">|</li>
<li><a class="nodec social-link icon-github" href="https://github.com/mrmoje" target="_blank"></a></li>
<li><a class="nodec social-link icon-twitter" href="https://twitter.com/mrmoje" target="_blank"></a></li>
<li><a class="nodec social-link icon-rss" href="http://tdt.rocks/feed/atom.xml" target="_blank"></a></li>
<li><a class="nodec social-link icon-stackoverflow" href="https://stackoverflow.com/users/1002644/moje" target="_blank"></a></li>
</ul>
<h1 class="header-name">
<a id="sitename" class="nodec" href="http://tdt.rocks">TDT</a>
</h1>
</div>
</div>
</header> <!-- /.header --> <div class="container">
<div class="post full-post">
<h1 class="post-title">
<a href="/linux_network_interface_naming.html" title="Permalink to Linux network interface naming">Linux network interface naming</a>
</h1>
<hr>
<ul class="list-inline">
<li class="post-date">
<a class="text-muted" href="/linux_network_interface_naming.html" title="2015-12-18T03:25:00+03:00">December 18, 2015</a>
</li>
<li class="muted">·</li>
<li class="post-category">
<a href="http://tdt.rocks/category/networking.html">Networking</a>
</li>
<li class="muted">·</li>
<li>
<a href="/tag/linux.html">linux</a>, <a href="/tag/systemd.html">systemd</a>, <a href="/tag/network interfaces.html">network interfaces</a> </li>
<li class="muted">·</li>
<li>
<address class="post-author">
By <a href="http://tdt.rocks/author/james-nzomo.html">James Nzomo</a>
</address>
</li>
</ul>
<div class="post-content">
<h1>Intro</h1>
<p>If you are running a recent ubuntu release ( > 15.XX ), you've probably noticed
that your net interfaces have been "rebranded". Maybe this noticing came in the
form of your sripts being broken....your <code>/etc/network/if-up.d/XXX</code> script or
vagrant-libvirt deploy failed because you hard coded an interface name in your
scripts (bad practice which im guilty of). It worked previously on your
old-release, then you had to upgrade...but I digress.</p>
<p>In this post, I'll try talking about how net devices get their names, the schemes
employed and the tech behind the schemes.</p>
<hr>
<h1>The classic naming scheme - <code>eth<0-n></code></h1>
<p>Not so long ago, without any devops intervention, interface names were decided
solely by the Kernel based on the order in which they are enumerated which in
turn is based on the order in which their modules/drivers are loaded and then,
where multiple NICs catered for by the same driver are present, they'd be named
in the order in which they were discovered which in turn is again affected by
the order in which the PCI device list is enumerated.</p>
<p>When its all done, you'd have something like this :-</p>
<p><code>eth<index></code> = ethernet, <code>wlan<index></code> = wireless, <code>usb<index></code> = usbnet - prolly phone-tethered</p>
<p>While the scheme is good enough to tell about the type of connection, there's
not much in the way of name predictability and telling about the nature of
the hardware that provides a given interface i.e. are <code>eth0</code> and <code>eth1</code> provided
by different ports on the same NIC? Is <code>eth2</code> provided by a USB adapter?</p>
<p>Another problem is that if you leave it all up to the powers behind the scheme, the
device naming will probably not be the same after kernel, NIC or motherboard
upgrades or sometimes even reboots.</p>
<p>It's possible to get around the above mentioned limitations using <a href="classic_naming_workarounds">scripts
and udev rules</a> but we live in modern times and
techies should not be bothered to jump through those hoops just to sort out
something that should be automagic.</p>
<hr>
<h1>biosdevname - <code>em<port></code>, <code>p<slot>p<port></code></h1>
<p>One of the efforts at bringing order out of chaos is dell's <a href="http://linux.dell.com/biosdevname/">biosdevname</a>
project which according to the project description is <q>a udev helper for naming
devices per BIOS names.</q> This helper-utility determines device names based on
the <q>intended order of network devices</q> as suggested by the BIOS.</p>
<p>With the default policy, the naming scheme of it goes like so:- </p>
<ul>
<li>On-board net devices get named <code>em<port>[_<virtual instance>]</code> </li>
<li>Add-on NICs devices get named <code>p<slot>p<port>[_<virtual instance>]</code></li>
</ul>
<p>where:- </p>
<ul>
<li><code>em</code> = <a href="http://linux.dell.com/files/whitepapers/consistent_network_device_naming_in_linux.pdf">ethernet-on-motherboard</a>,</li>
<li><code><slot></code> = the respective PCI slot,</li>
<li><code><port></code> the port number...for multi-port NICs.</li>
<li><code><virtual instance></code> is the SRIOV and/or NPAR instance index</li>
<li>The "p"s in the Add-on card scheme stand for pci slot and port respectively</li>
</ul>
<p>The above scheme is implemented here:- <a href="http://linux.dell.com/cgi-bin/cgit.cgi/biosdevname.git/tree/src/naming_policy.c?id=e51172768cec37ab0a350e439d2827b0c4e604a4#n31">naming_policy.c</a></p>
<p>If you have the utility installed, you can try it out by booting your kernel
with <code>biosdevname=1</code> option or just run <code>biosdevname -i eth0 #(swap eth0
with any interface you have)</code> from the terminal. If conditions are right,
you should get something along the lines of <code>em1</code> or <code>p1p1</code>.</p>
<p>With this utility, names are stable, predictable and you can also tell what's embedded
and what's slotted in...but it has it's limitations, one of them being that it doesn't
cater for a wider range of interface types/devices. It refused to name my usb
ethernet dongle.</p>
<hr>
<h1>systemd udev - <code>eno<index></code>, <code>ens<slot>d<port></code></h1>
<p>Starting version 197, shortly after udev was absorbed into systemd source
tree, native predictable naming was added to the mix.</p>
<p>According to <a href="http://wiki.freedesktop.org/www/Software/systemd/PredictableNetworkInterfaceNames/">the systemd wiki on the topic</a>, and the
<a href="https://github.com/systemd/systemd/blob/3f65d73149cd0f64eb3fdb0c71f55f6c1133fefe/src/udev/udev-builtin-net_id.c">systemd-udev sources</a>, the names are generated based on:-</p>
<ul>
<li>firmware/bios-provided for on-board devices - <code><type>o<index>[d<dev_port>]</code></li>
<li>firmware/bios-provided for pci-express hotplug slot - <code><type>s<slot>[f<function>][d<dev_port>]</code></li>
<li>physical/geographical location for PCI devices -<br>
<code><type>[P<domain>]p<bus>s<slot>[f<function>][[d<dev_port>]|[u<port>][..][c<config>][i<interface>]]</code></li>
<li>the devices's MAC address - <code><type>x<MAC></code></li>
</ul>
<p>Where:-</p>
<ul>
<li><code><type></code> is a two character prefix that tells the nature of the device/connection:-
<code>en</code> for ethernet, <code>sl</code> = <a href="https://tools.ietf.org/html/rfc1055">Serial Line Internet Protocol</a>,
<code>wl</code> = Wireless LAN/Wi-Fi and <code>ww</code> for Wireless WAN (LTE/3g device, probably even WiMAX)</li>
<li><code><domain></code> is pci device domain.</li>
<li><code><function></code> = SRIOV(or maybe also NPAR?) number for multi-function PCI devices.</li>
<li><code>u<port></code> is a usb port</li>
</ul>
<p>Thus for example <code>eno1</code> is an onboard ethernet device, <code>enp8s0</code> should be an
ethernet interface provided by a device on bus #8 slot #0 with only 1 port and
<code>wlp9s0</code> should be an wlan interface provided by device on bus #9 slot #0.</p>
<p>On trying out a usb ethernet dongle, I got <code>enp0s29f7u1</code> and going by the
location/path scheme we can tell that it's an ethernet interface provided by a
usb device connected to a usb controller on PCI bus #0, device #29, with function #7
plugged into usb port #1.</p>
<h3>systemd-udev Naming Policy</h3>
<p>Net devices may have more than one name generated for them which you can
view by querying the udev database (filtering the results):- </p>
<div class="highlight"><pre><span></span><code>udevadm info -q property -p /sys/class/net/ens33 <span class="p">|</span> grep ID_NET_NAME
<span class="nv">ID_NET_NAME_MAC</span><span class="o">=</span>enx112233445566
<span class="nv">ID_NET_NAME_PATH</span><span class="o">=</span>enp2s0
<span class="nv">ID_NET_NAME_SLOT</span><span class="o">=</span>ens33
</code></pre></div>
<p>In the above example, we have names by mac, location and bios provided index.
The choice of name is determined by a list if policies defined for <code>NamePolicy</code>
in the respective link config file (see <code>man systemd.link</code>). To find out what
link file is in use, query udevadm like so:-</p>
<div class="highlight"><pre><span></span><code>udevadm info -q property -p /sys/class/net/ens33 <span class="p">|</span> grep LINK_FILE
<span class="nv">ID_NET_LINK_FILE</span><span class="o">=</span>/lib/systemd/network/99-default.link
</code></pre></div>
<p>I get 99-default.link, contents of which are:-</p>
<div class="highlight"><pre><span></span><code>cat /lib/systemd/network/99-default.link
<span class="o">[</span>Link<span class="o">]</span>
<span class="nv">NamePolicy</span><span class="o">=</span>kernel database onboard slot path
<span class="nv">MACAddressPolicy</span><span class="o">=</span>persistent
</code></pre></div>
<p>Looking at the <code>NamePolicy</code> entry, the precedence is defined by the order
in which they appear and the first successful one is used to set the device name.
In this case with ens33 being chosen, <code>kernel</code>, <code>database</code> and <code>onboard</code> failed,
<code>slot</code> passed and <code>path</code> wasn't considered.</p>
<h1>Outro</h1>
<p>systemd-udev is now standard on most big name distros (ubuntu included) and has
naturally superseded biosdevname where it reigned. There is no need to sweat it out
with unpredictable interface names like the techies of yesterday but just in case
you want to, you can disable all manner of predictability by passing <code>net.ifnames=0</code>
and <code>biosdevname=0</code> to the kernel at boot time.</p>
<h3>Resources, Refs & google juice:-</h3>
<ul>
<li><a href="http://wiki.freedesktop.org/www/Software/systemd/PredictableNetworkInterfaceNames/" target="_blank">wiki.freedesktop.org article on the subject</a></li>
<li><a href="https://github.com/systemd/systemd/blob/3f65d73149cd0f64eb3fdb0c71f55f6c1133fefe/src/udev/udev-builtin-net_id.c" target="_blank">Well commented source on systemd net-dev naming</a></li>
<li><a href="http://linux.dell.com/biosdevname/" target="_blank">biosdevname homepage</a></li>
<li><a href="http://linux.dell.com/cgi-bin/cgit.cgi/biosdevname.git/tree/src/naming_policy.c?id=e51172768cec37ab0a350e439d2827b0c4e604a4#n31" target="_blank">biosdevname naming policy source</a></li>
<li><a href="https://ivi.fnwi.uva.nl/sne/air//wiki/LogicalInterfaceNames/" target="_blank">An ice article on classic naming scheme and problem workarounds</a></li>
<li><a href="http://www.amazon.com/gp/product/B00PKTGLWM?psc=1&redirect=true&ref_=oh_aui_d_detailpage_o00" target="_blank">How Linux Works: What Every Superuser Should Know</a> by Brian Ward</li>
</ul>
</div>
</div>
<hr class="separator">
<div>
<div id="disqus_thread">
<script>
var disqus_shortname = 'tdtrocks';
(function() {
var dsq = document.createElement('script');
dsq.type = 'text/javascript';
dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] ||
document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>
Please enable JavaScript to view the
<a href="https://disqus.com/?ref_noscript=tdtrocks">
comments powered by Disqus.
</a>
</noscript>
<a href="https://disqus.com" class="dsq-brlink">
blog comments powered by <span class="logo-disqus">Disqus</span>
</a>
</div>
</div>
</div>
<footer class="footer">
<div class="container">
<p class="text-center">
©Twenny Nineteen - James Nzomo, <a href="" target="_blank"></a> unless otherwise noted.
</p>
<div class="text-center">
Generated by <a href="http://getpelican.com" target="_blank">Pelican</a>
with a <a href="http://github.com/mrmoje/pelican-alchemy" target="_blank">copy-pasta</a>
of <a href="https://nairobilug.or.ke" target="_blank" >NairobiLUG's</a>
<a href="http://github.com/nairobilug/pelican-alchemy" target="_blank">alchemy</a> theme, <br/>
which inturn is a copy-pasta of Porter's <a href="https://github.com/porterjamesj/crowsfoot" target="_blank">crowsfoot</a> theme. <br/>
--- end of <a href="//tdt.rocks/pages/glossary#google-juice">google juice</a> ---.
</div>
</div>
</footer> <!-- /.footer -->
<script src="http://tdt.rocks/theme/js/jquery.min.js"></script>
<script src="http://tdt.rocks/theme/js/bootstrap.min.js"></script>
</body> <!-- 42 -->
</html>