diff options
39 files changed, 1836 insertions, 300 deletions
diff --git a/CODING_STYLE b/CODING_STYLE index 98d99dcdaa..cf86de5f62 100644 --- a/CODING_STYLE +++ b/CODING_STYLE @@ -321,3 +321,20 @@ parse values the same way on all architectures and cannot expose off_t values over D-Bus. To avoid any confusion regarding conversion and ABIs, always use simply uint64_t directly. + +- Commit message subject lines should be prefixed with an appropriate + component name of some kind. For example "journal: ", "nspawn: " and + so on. + +- Do not use "Signed-Off-By:" in your commit messages. That's a kernel + thing we don't do in the systemd project. + +- Avoid leaving long-running child processes around, i.e. fork()s that + are not followed quickly by an execv() in the child. Resource + management is unclear in this case, and memory CoW will result in + penalties in the parent much much later on. + +- Don't block execution for arbitrary amounts of time using usleep() + or a similar call, unless you really know what you do. Just "giving + something some time", or so is a lazy excuse. Always wait for the + proper event, instead of doing time-based poll loops. @@ -138,7 +138,7 @@ CHANGES WITH 227: only intermittendly, and even restores state if the previous system shutdown was abrupt rather than clean. - * Galician, Turkish and Korean translations were added. + * Galician, Serbian, Turkish and Korean translations were added. Contributions from: diff --git a/catalog/systemd.sr.catalog b/catalog/systemd.sr.catalog new file mode 100644 index 0000000000..cf700c477b --- /dev/null +++ b/catalog/systemd.sr.catalog @@ -0,0 +1,262 @@ +# This file is part of systemd. +# +# Copyright 2012 Lennart Poettering +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# systemd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with systemd; If not, see <http://www.gnu.org/licenses/>. + +# Message catalog for systemd's own messages +# Serbian translation + +# Формат каталога је документован на +# http://www.freedesktop.org/wiki/Software/systemd/catalog + +# Да бисте видели зашто ово радимо, погледајте https://xkcd.com/1024/ + +-- f77379a8490b408bbe5f6940505a777b +Subject: Журнал је покренут +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Системски журналски процес се покренуо, отворио журналске +датотеке за упис и спреман је за обраду захтева. + +-- d93fb3c9c24d451a97cea615ce59c00b +Subject: Журнал је заустављен +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Системски журналски процес се зауставио и затворио све тренутно +отворене журналске датотеке. + +-- a596d6fe7bfa4994828e72309e95d61e +Subject: Поруке од услуге су утишане +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: man:journald.conf(5) + +Услуга је уписала сувише порука за једно време. Поруке +од услуге су одбачене. + +Знајте да су само поруке од ове услуге одбачене, друге +услуге нису захваћене овим. + +Ограничења која подешавају начин на који се поруке одбацују се могу подесити +помоћу „RateLimitInterval=“ и „RateLimitBurst=“ параметара унутар датотеке +/etc/systemd/journald.conf. Погледајте journald.conf(5) за појединости. + +-- e9bf28e6e834481bb6f48f548ad13606 +Subject: Журналске поруке су изгубљене +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Поруке кернела су изгубљене јер журналски систем није могао да их +обради довољно брзо. + +-- fc2e22bc6ee647b6b90729ab34a250b1 +Subject: Процес @COREDUMP_PID@ (@COREDUMP_COMM@) је избацио своје језгро +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: man:core(5) + +Процес @COREDUMP_PID@ (@COREDUMP_COMM@) је пао и избацио своје језгро. + +Ово обично значи да постоји грешка у програму који је пао и ова +грешка треба да се пријави продавцу. + +-- 8d45620c1a4348dbb17410da57c60c66 +Subject: Нова сесија @SESSION_ID@ је направљена за корисника @USER_ID@ +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat + +Нова сесија са ИБ-ом @SESSION_ID@ је направљена за корисника @USER_ID@. + +Водећи процес сесије је @LEADER@. + +-- 3354939424b4456d9802ca8333ed424a +Subject: Сесија @SESSION_ID@ је окончана +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat + +Сесија са ИБ-ом @SESSION_ID@ је окончана. + +-- fcbefc5da23d428093f97c82a9290f7b +Subject: Ново седиште @SEAT_ID@ је сада доступно +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat + +Ново седиште @SEAT_ID@ је исподешавано и сада је доступно. + +-- e7852bfe46784ed0accde04bc864c2d5 +Subject: Седиште @SEAT_ID@ је сада уклоњено +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel +Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat + +Седиште @SEAT_ID@ је сада уклоњено и више није доступно. + +-- c7a787079b354eaaa9e77b371893cd27 +Subject: Време је промењено +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Системски сат је сада подешен на @REALTIME@ микросекунде након 1. јануара 1970. године. + +-- 45f82f4aef7a4bbf942ce861d1f20990 +Subject: Временска зона је промењена на @TIMEZONE@ +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Временска зона је промењена на @TIMEZONE@. + +-- b07a249cd024414a82dd00cd181378ff +Subject: Подизање система је сада готово +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Све системске услуге које су заказане за подизање су успешно покренуте. +Знајте да ово не значи да је машина сада беспослена јер услуге могу +и даље бити заузете завршавањем покретања система. + +Подизање кернела је трајало @KERNEL_USEC@ микросекунде. + +Подизање почетног РАМ диска је трајало @INITRD_USEC@ микросекунде. + +Подизање корисничких програма је трајало @USERSPACE_USEC@ микросекунде. + +-- 6bbd95ee977941e497c48be27c254128 +Subject: Системско стање спавања @SLEEP@ започето +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Систем је сада ушао у @SLEEP@ стање спавања. + +-- 8811e6df2a8e40f58a94cea26f8ebf14 +Subject: Системско стање спавања @SLEEP@ напуштено +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Систем је изашао из @SLEEP@ стања спавања. + +-- 98268866d1d54a499c4e98921d93bc40 +Subject: Гашење система започето +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Систем-де гашење је започето. Гашење је сада почело и све +системске услуге су окончане и сви системи датотека откачени. + +-- 7d4958e842da4a758f6c1cdc7b36dcc5 +Subject: Јединица @UNIT@ је почела са покретањем +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Јединица @UNIT@ је почела са покретањем. + +-- 39f53479d3a045ac8e11786248231fbf +Subject: Јединица @UNIT@ је завршила са покретањем +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Јединица @UNIT@ је завршила са покретањем. + +Исход покретања је @RESULT@. + +-- de5b426a63be47a7b6ac3eaac82e2f6f +Subject: Јединица @UNIT@ је почела са гашењем +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Јединица @UNIT@ је почела са гашењем. + +-- 9d1aaa27d60140bd96365438aad20286 +Subject: Јединица @UNIT@ је завршила са гашењем +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Јединица @UNIT@ је завршила са гашењем. + +-- be02cf6855d2428ba40df7e9d022f03d +Subject: Јединица @UNIT@ је пукла +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Јединица @UNIT@ је пукла. + +Исход је @RESULT@. + +-- d34d037fff1847e6ae669a370e694725 +Subject: Јединица @UNIT@ је почела са поновним учитавањем свог подешавања +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Јединица @UNIT@ је почела са поновним учитавањем свог подешавања + +-- 7b05ebc668384222baa8881179cfda54 +Subject: Јединица @UNIT@ је завршила са поновним учитавањем свог подешавања +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Јединица @UNIT@ је завршила са поновним учитавањем свог подешавања + +Исход је @RESULT@. + +-- 641257651c1b4ec9a8624d7a40a9e1e7 +Subject: Процес @EXECUTABLE@ није могао бити извршен +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Процес @EXECUTABLE@ није могао бити извршен и пукао је. + +Овај процес је вратио број грешке @ERRNO@. + +-- 0027229ca0644181a76c4e92458afa2e +Subject: Једна или више порука није могло бити прослеђено системском записнику +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Једна или више порука није могло бити прослеђено „syslog“ услузи +која ради упоредно са журнал-деом. Ово обично значи да спроведена +„syslog“ услуга није могла да издржи брзину свих надолазећих +порука у реду. + +-- 1dee0369c7fc4736b7099b38ecb46ee7 +Subject: Тачка качења није празна +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Директоријум @WHERE@ је наведен као тачка качења (друго поље у +/etc/fstab датотеци или у „Where=“ пољу систем-де јединичне датотеке) +и он није празан. Ово не утиче на качење али ће већ постојеће датотеке у +овом директоријуму постати недоступне. Да бисте видели ове недоступне +датотеке, ручно прикачите основни систем датотека у другу +путању. + +-- 24d8d4452573402496068381a6312df2 +Subject: Виртуелна машина или контејнер је покренут(а) +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Виртуелна машина @NAME@ са водећим ПИБ-ом @LEADER@ је +покренута и сада је спремна за коришћење. + +-- 58432bd3bace477cb514b56381b8a758 +Subject: Виртуелна машина или контејнер је окончан(а) +Defined-By: systemd +Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel + +Виртуелна машина @NAME@ са водећим ПИБ-ом @LEADER@ је +угашена. diff --git a/configure.ac b/configure.ac index d75a02623b..aabb5e4fe4 100644 --- a/configure.ac +++ b/configure.ac @@ -321,6 +321,7 @@ AC_CHECK_DECLS([IFLA_INET6_ADDR_GEN_MODE, IFLA_GRE_ENCAP_DPORT, IFLA_BRIDGE_VLAN_INFO, IFLA_BRPORT_LEARNING_SYNC, + IFLA_BR_PRIORITY, NDA_IFINDEX, IFA_FLAGS], [], [], [[ diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb index 3e49449ae9..b6a5456dfb 100644 --- a/hwdb/60-keyboard.hwdb +++ b/hwdb/60-keyboard.hwdb @@ -648,6 +648,10 @@ evdev:atkbd:dmi:bvn*:bvr*:svnLENOVO*:pn*IdeaPad*Z370*:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*Lenovo*V480*:pvr* KEYBOARD_KEY_f1=f21 +# Thinkpad Yoga 12 (2015) +evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:pvrThinkPadS1Yoga12* + KEYBOARD_KEY_d9=direction + # enhanced USB keyboard evdev:input:b0003v04B3p301B* KEYBOARD_KEY_90001=prog1 # ThinkVantage diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml index 58e6fd1780..632e6363f6 100644 --- a/man/systemd-analyze.xml +++ b/man/systemd-analyze.xml @@ -93,7 +93,7 @@ <command>systemd-analyze</command> <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="plain">set-log-level</arg> - <arg choice="opt"><replaceable>LEVEL</replaceable></arg> + <arg choice="plain"><replaceable>LEVEL</replaceable></arg> </cmdsynopsis> <cmdsynopsis> <command>systemd-analyze</command> diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml index 49f44d2922..494f97aad1 100644 --- a/man/systemd.journal-fields.xml +++ b/man/systemd.journal-fields.xml @@ -258,6 +258,16 @@ <variablelist> <varlistentry> <term> + <option>audit</option> + </term> + <listitem> + <para>for those read from the kernel audit subsystem + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term> <option>driver</option> </term> <listitem> diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 9f0afad853..70311ca9d9 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -277,6 +277,43 @@ </variablelist> </refsect1> + <refsect1> + <title>[Bridge] Section Options</title> + + <para>The <literal>[Bridge]</literal> section only applies for + netdevs of kind <literal>bridge</literal>, and accepts the + following key:</para> + + <variablelist class='network-directives'> + <varlistentry> + <term><varname>HelloTimeSec=</varname></term> + <listitem> + <para>HelloTimeSec specifies the number of seconds a hello packet is + sent out by the root bridge and the designated bridges. Hello packets are + used to communicate information about the topology throughout the entire + bridged local area network.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>MaxAgeSec=</varname></term> + <listitem> + <para>MaxAgeSec specifies the number of seconds of maximum message age. + If the last seen (received) hello packet is more than this number of + seconds old, the bridge in question will start the takeover procedure + in attempt to become the Root Bridge itself.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>ForwardDelaySec=</varname></term> + <listitem> + <para>ForwardDelaySec specifies the number of seconds spent in each + of the Listening and Learning states before the Forwarding state is entered.</para> + </listitem> + </varlistentry> + </variablelist> + + </refsect1> + <refsect1> <title>[VLAN] Section Options</title> diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 2bb793619e..a27f2ff99e 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -545,6 +545,14 @@ <literal>global</literal>.</para> </listitem> </varlistentry> + <varlistentry> + <term><varname>PreferredSource=</varname></term> + <listitem> + <para>The preferred source address of the route. The address + must be in the format described in + <citerefentry project='man-pages'><refentrytitle>inet_pton</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para> + </listitem> + </varlistentry> </variablelist> </refsect1> diff --git a/po/LINGUAS b/po/LINGUAS index 3d6a03e421..93c5c53023 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -10,6 +10,7 @@ pt_BR ru uk sv +sr es zh_TW be diff --git a/po/sr.po b/po/sr.po new file mode 100644 index 0000000000..7f9b2b31cd --- /dev/null +++ b/po/sr.po @@ -0,0 +1,606 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n" +"POT-Creation-Date: 2015-10-03 18:14+0200\n" +"PO-Revision-Date: 2015-10-03 21:01+0200\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.4\n" +"Last-Translator: Марко М. Костић (Marko M. Kostić) <marko.m.kostic@gmail." +"com>\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"Language: sr\n" + +#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1 +msgid "Send passphrase back to system" +msgstr "Пошаљите фразу ка систему" + +#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2 +msgid "" +"Authentication is required to send the entered passphrase back to the system." +msgstr "" +"Потребно је да се идентификујете да бисте послали фразу назад у систем." + +#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3 +msgid "Manage system services or other units" +msgstr "Управљајте системским услугама и другим јединицама" + +#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4 +msgid "Authentication is required to manage system services or other units." +msgstr "" +"Потребно је да се идентификујете да бисте управљали системским услугама или " +"другим јединицама." + +#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:5 +msgid "Manage system service or unit files" +msgstr "Управљајте системском услугом или јединичним датотекама" + +#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:6 +msgid "Authentication is required to manage system service or unit files." +msgstr "" +"Потребно је да се идентификујете да бисте управљали системском услугом или " +"јединичним датотекама." + +#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:7 +msgid "Set or unset system and service manager environment variables" +msgstr "Мењајте променљиве окружења на систему и унутар управника услуга" + +#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:8 +msgid "" +"Authentication is required to set or unset system and service manager " +"environment variables." +msgstr "" +"Потребно је да се идентификујете да бисте мењали променљиве окружења на " +"систему и унутар управника услуга." + +#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9 +msgid "Reload the systemd state" +msgstr "Поново учитајте стање систем-деа" + +#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:10 +msgid "Authentication is required to reload the systemd state." +msgstr "" +"Потребно је да се идентификујете да бисте поново учитали стање систем-деа." + +#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:1 +msgid "Set host name" +msgstr "Поставите назив машине" + +#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:2 +msgid "Authentication is required to set the local host name." +msgstr "Потребно је да се идентификујете да бисте поставили назив машине." + +#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:3 +msgid "Set static host name" +msgstr "Поставите статички назив машине" + +#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:4 +msgid "" +"Authentication is required to set the statically configured local host name, " +"as well as the pretty host name." +msgstr "" +"Потребно је да се идентификујете да бисте поставили статички назив машине и " +"да бисте поставили леп назив машине." + +#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5 +msgid "Set machine information" +msgstr "Поставите податке о машини" + +#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:6 +msgid "Authentication is required to set local machine information." +msgstr "" +"Потребно је да се идентификујете да бисте поставили податке о локалној " +"машини." + +#: ../src/import/org.freedesktop.import1.policy.in.h:1 +msgid "Import a VM or container image" +msgstr "Увезите ВМ или слику контејнера" + +#: ../src/import/org.freedesktop.import1.policy.in.h:2 +msgid "Authentication is required to import a VM or container image" +msgstr "" +"Потребно је да се идентификујете да бисте увезли виртуелну машину или слику " +"контејнера" + +#: ../src/import/org.freedesktop.import1.policy.in.h:3 +msgid "Export a VM or container image" +msgstr "Извезите ВМ или слику контејнера" + +#: ../src/import/org.freedesktop.import1.policy.in.h:4 +msgid "Authentication is required to export a VM or container image" +msgstr "" +"Потребно је да се идентификујете да бисте извезли виртуелну машину или слику " +"контејнера" + +#: ../src/import/org.freedesktop.import1.policy.in.h:5 +msgid "Download a VM or container image" +msgstr "Преузмите ВМ или слику контејнера" + +#: ../src/import/org.freedesktop.import1.policy.in.h:6 +msgid "Authentication is required to download a VM or container image" +msgstr "" +"Потребно је да се идентификујете да бисте преузели виртуелну машину или " +"слику контејнера" + +#: ../src/locale/org.freedesktop.locale1.policy.in.h:1 +msgid "Set system locale" +msgstr "Поставите основни језик система" + +#: ../src/locale/org.freedesktop.locale1.policy.in.h:2 +msgid "Authentication is required to set the system locale." +msgstr "" +"Потребно је да се идентификујете да бисте поставили основни језик система." + +#: ../src/locale/org.freedesktop.locale1.policy.in.h:3 +msgid "Set system keyboard settings" +msgstr "Поставите подешавање системске тастатуре" + +#: ../src/locale/org.freedesktop.locale1.policy.in.h:4 +msgid "Authentication is required to set the system keyboard settings." +msgstr "" +"Потребно је да се идентификујете да бисте поставили подешавања системске " +"тастатуре." + +#: ../src/login/org.freedesktop.login1.policy.in.h:1 +msgid "Allow applications to inhibit system shutdown" +msgstr "Дозволите програмима да спрече гашење система" + +#: ../src/login/org.freedesktop.login1.policy.in.h:2 +msgid "" +"Authentication is required for an application to inhibit system shutdown." +msgstr "" +"Потребно је да се идентификујете да бисте дозволили програму да спречи " +"гашење система." + +#: ../src/login/org.freedesktop.login1.policy.in.h:3 +msgid "Allow applications to delay system shutdown" +msgstr "Дозволите програмима да одложе гашење система" + +#: ../src/login/org.freedesktop.login1.policy.in.h:4 +msgid "Authentication is required for an application to delay system shutdown." +msgstr "" +"Потребно је да се идентификујете да бисте дозволили програму да одложи " +"гашење система." + +#: ../src/login/org.freedesktop.login1.policy.in.h:5 +msgid "Allow applications to inhibit system sleep" +msgstr "Дозволите програмима да спрече спавање система" + +#: ../src/login/org.freedesktop.login1.policy.in.h:6 +msgid "Authentication is required for an application to inhibit system sleep." +msgstr "" +"Потребно је да се идентификујете да бисте дозволили програму да спречи " +"спавање система." + +#: ../src/login/org.freedesktop.login1.policy.in.h:7 +msgid "Allow applications to delay system sleep" +msgstr "Дозволите програмима да одложе спавање система" + +#: ../src/login/org.freedesktop.login1.policy.in.h:8 +msgid "Authentication is required for an application to delay system sleep." +msgstr "" +"Потребно је да се идентификујете да бисте дозволили програму да одложи " +"спавање система." + +#: ../src/login/org.freedesktop.login1.policy.in.h:9 +msgid "Allow applications to inhibit automatic system suspend" +msgstr "Дозволите програмима да спрече самосталну обуставу система" + +#: ../src/login/org.freedesktop.login1.policy.in.h:10 +msgid "" +"Authentication is required for an application to inhibit automatic system " +"suspend." +msgstr "" +"Потребно је да се идентификујете да бисте дозволили програму да спречи " +"самосталну обуставу система." + +#: ../src/login/org.freedesktop.login1.policy.in.h:11 +msgid "Allow applications to inhibit system handling of the power key" +msgstr "Дозволите програмима да спрече систему управљање дугметом за напајање" + +#: ../src/login/org.freedesktop.login1.policy.in.h:12 +msgid "" +"Authentication is required for an application to inhibit system handling of " +"the power key." +msgstr "" +"Потребно је да се идентификујете да бисте дозволили програму да спречи " +"систему управљање дугметом за напајање." + +#: ../src/login/org.freedesktop.login1.policy.in.h:13 +msgid "Allow applications to inhibit system handling of the suspend key" +msgstr "Дозволите програмима да спрече систему управљање дугметом за обуставу" + +#: ../src/login/org.freedesktop.login1.policy.in.h:14 +msgid "" +"Authentication is required for an application to inhibit system handling of " +"the suspend key." +msgstr "" +"Потребно је да се идентификујете да бисте дозволили програму да спречи " +"систему управљање дугметом за обуставу." + +#: ../src/login/org.freedesktop.login1.policy.in.h:15 +msgid "Allow applications to inhibit system handling of the hibernate key" +msgstr "Дозволите програмима да спрече систему управљање дугметом за спавање" + +#: ../src/login/org.freedesktop.login1.policy.in.h:16 +msgid "" +"Authentication is required for an application to inhibit system handling of " +"the hibernate key." +msgstr "" +"Потребно је да се идентификујете да бисте дозволили програму да спречи " +"систему управљање дугметом за спавање." + +#: ../src/login/org.freedesktop.login1.policy.in.h:17 +msgid "Allow applications to inhibit system handling of the lid switch" +msgstr "" +"Дозволите програмима да спрече систему да уради било шта приликом заклапања " +"екрана" + +#: ../src/login/org.freedesktop.login1.policy.in.h:18 +msgid "" +"Authentication is required for an application to inhibit system handling of " +"the lid switch." +msgstr "" +"Потребно је да се идентификујете да бисте дозволили програму да спречи " +"систему да уради било шта приликом заклапања екрана." + +#: ../src/login/org.freedesktop.login1.policy.in.h:19 +msgid "Allow non-logged-in users to run programs" +msgstr "Дозволите непријављеним корисницима да покрећу програме" + +#: ../src/login/org.freedesktop.login1.policy.in.h:20 +msgid "Authentication is required to run programs as a non-logged-in user." +msgstr "" +"Потребно је да се идентификујете да бисте покретали програме као непријављен " +"корисник." + +#: ../src/login/org.freedesktop.login1.policy.in.h:21 +msgid "Allow attaching devices to seats" +msgstr "Дозволите качење уређаја на седишта" + +#: ../src/login/org.freedesktop.login1.policy.in.h:22 +msgid "Authentication is required for attaching a device to a seat." +msgstr "Потребно је да се идентификујете да бисте закачили уређај на седиште." + +#: ../src/login/org.freedesktop.login1.policy.in.h:23 +msgid "Flush device to seat attachments" +msgstr "Испери уређај да би уседиштио закачено" + +#: ../src/login/org.freedesktop.login1.policy.in.h:24 +msgid "" +"Authentication is required for resetting how devices are attached to seats." +msgstr "" +"Потребно је да се идентификујете да бисте поново подесили како се уређаји " +"каче на седишта." + +#: ../src/login/org.freedesktop.login1.policy.in.h:25 +msgid "Power off the system" +msgstr "Искључите систем" + +#: ../src/login/org.freedesktop.login1.policy.in.h:26 +msgid "Authentication is required for powering off the system." +msgstr "Потребно је да се идентификујете да бисте искључили систем." + +#: ../src/login/org.freedesktop.login1.policy.in.h:27 +msgid "Power off the system while other users are logged in" +msgstr "Искључите систем док су други корисници пријављени" + +#: ../src/login/org.freedesktop.login1.policy.in.h:28 +msgid "" +"Authentication is required for powering off the system while other users are " +"logged in." +msgstr "" +"Потребно је да се идентификујете да бисте искључили систем док су други " +"корисници пријављени." + +#: ../src/login/org.freedesktop.login1.policy.in.h:29 +msgid "Power off the system while an application asked to inhibit it" +msgstr "Искључите систем иако је програм затражио да се спречи гашење" + +#: ../src/login/org.freedesktop.login1.policy.in.h:30 +msgid "" +"Authentication is required for powering off the system while an application " +"asked to inhibit it." +msgstr "" +"Потребно је да се идентификујете да бисте искључили систем иако је програм " +"затражио да се спречи гашење система." + +#: ../src/login/org.freedesktop.login1.policy.in.h:31 +msgid "Reboot the system" +msgstr "Поново покрените систем" + +#: ../src/login/org.freedesktop.login1.policy.in.h:32 +msgid "Authentication is required for rebooting the system." +msgstr "Потребно је да се идентификујете да бисте поново покренули систем." + +#: ../src/login/org.freedesktop.login1.policy.in.h:33 +msgid "Reboot the system while other users are logged in" +msgstr "Поново покрените систем док су други корисници пријављени" + +#: ../src/login/org.freedesktop.login1.policy.in.h:34 +msgid "" +"Authentication is required for rebooting the system while other users are " +"logged in." +msgstr "" +"Потребно је да се идентификујете да бисте поново покренули систем док су " +"други корисници пријављени." + +#: ../src/login/org.freedesktop.login1.policy.in.h:35 +msgid "Reboot the system while an application asked to inhibit it" +msgstr "Поново покрените систем иако је програм затражио да се спречи гашење" + +#: ../src/login/org.freedesktop.login1.policy.in.h:36 +msgid "" +"Authentication is required for rebooting the system while an application " +"asked to inhibit it." +msgstr "" +"Потребно је да се идентификујете да бисте поново покренули систем иако је " +"програм затражио да се спречи гашење система." + +#: ../src/login/org.freedesktop.login1.policy.in.h:37 +msgid "Suspend the system" +msgstr "Обуставите систем" + +#: ../src/login/org.freedesktop.login1.policy.in.h:38 +msgid "Authentication is required for suspending the system." +msgstr "Потребно је да се идентификујете да бисте обуставили систем." + +#: ../src/login/org.freedesktop.login1.policy.in.h:39 +msgid "Suspend the system while other users are logged in" +msgstr "Обуставите систем док су други корисници пријављени" + +#: ../src/login/org.freedesktop.login1.policy.in.h:40 +msgid "" +"Authentication is required for suspending the system while other users are " +"logged in." +msgstr "" +"Потребно је да се идентификујете да бисте обуставили систем док су други " +"корисници пријављени." + +#: ../src/login/org.freedesktop.login1.policy.in.h:41 +msgid "Suspend the system while an application asked to inhibit it" +msgstr "Обуставите систем иако је програм затражио да се спречи обустава" + +#: ../src/login/org.freedesktop.login1.policy.in.h:42 +msgid "" +"Authentication is required for suspending the system while an application " +"asked to inhibit it." +msgstr "" +"Потребно је да се идентификујете да бисте обуставили систем иако је програм " +"затражио да се спречи обустава система." + +#: ../src/login/org.freedesktop.login1.policy.in.h:43 +msgid "Hibernate the system" +msgstr "Успавајте систем" + +#: ../src/login/org.freedesktop.login1.policy.in.h:44 +msgid "Authentication is required for hibernating the system." +msgstr "Потребно је да се идентификујете да бисте успавали систем." + +#: ../src/login/org.freedesktop.login1.policy.in.h:45 +msgid "Hibernate the system while other users are logged in" +msgstr "Успавајте систем док су други корисници пријављени" + +#: ../src/login/org.freedesktop.login1.policy.in.h:46 +msgid "" +"Authentication is required for hibernating the system while other users are " +"logged in." +msgstr "" +"Потребно је да се идентификујете да бисте успавали систем док су други " +"корисници пријављени." + +#: ../src/login/org.freedesktop.login1.policy.in.h:47 +msgid "Hibernate the system while an application asked to inhibit it" +msgstr "Успавајте систем иако је програм затражио да се спречи спавање" + +#: ../src/login/org.freedesktop.login1.policy.in.h:48 +msgid "" +"Authentication is required for hibernating the system while an application " +"asked to inhibit it." +msgstr "" +"Потребно је да се идентификујете да бисте успавали систем иако је програм " +"затражио да се спречи успављивање система." + +#: ../src/login/org.freedesktop.login1.policy.in.h:49 +msgid "Manage active sessions, users and seats" +msgstr "Управљајте покренутим сесијама, корисницима и седиштима" + +#: ../src/login/org.freedesktop.login1.policy.in.h:50 +msgid "" +"Authentication is required for managing active sessions, users and seats." +msgstr "" +"Потребно је да се идентификујете да бисте управљали покренутим сесијама, " +"корисницима и седиштима." + +#: ../src/login/org.freedesktop.login1.policy.in.h:51 +msgid "Lock or unlock active sessions" +msgstr "Закључајте или откључајте покренуте сесије" + +#: ../src/login/org.freedesktop.login1.policy.in.h:52 +msgid "Authentication is required to lock or unlock active sessions." +msgstr "" +"Потребно је да се идентификујете да бисте закључавали или откључавали " +"покренуте сесије." + +#: ../src/login/org.freedesktop.login1.policy.in.h:53 +msgid "Allow indication to the firmware to boot to setup interface" +msgstr "Напомените фирмверу да се подигне у режим подешавања интерфејса" + +#: ../src/login/org.freedesktop.login1.policy.in.h:54 +msgid "" +"Authentication is required to indicate to the firmware to boot to setup " +"interface." +msgstr "" +"Потребно је да се идентификујете да бисте напоменули фирмверу да се подигне " +"у режиму подешавања интерфејса." + +#: ../src/login/org.freedesktop.login1.policy.in.h:55 +msgid "Set a wall message" +msgstr "Поставите зидну поруку" + +#: ../src/login/org.freedesktop.login1.policy.in.h:56 +msgid "Authentication is required to set a wall message" +msgstr "Потребно је да се идентификујете да бисте поставили зидну поруку" + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:1 +msgid "Log into a local container" +msgstr "Пријавите се у локални контејнер" + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:2 +msgid "Authentication is required to log into a local container." +msgstr "" +"Потребно је да се идентификујете да бисте се пријавили у локални контејнер." + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:3 +msgid "Log into the local host" +msgstr "Пријавите се у локалног домаћина" + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:4 +msgid "Authentication is required to log into the local host." +msgstr "" +"Потребно је да се идентификујете да бисте се пријавили у локалног домаћина." + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:5 +msgid "Acquire a shell in a local container" +msgstr "Добијте приступ шкољци унутар локалног контејнера" + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:6 +msgid "Authentication is required to acquire a shell in a local container." +msgstr "" +"Потребно је да се идентификујете да бисте добили приступ шкољци унутар " +"локалног контејнера." + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:7 +msgid "Acquire a shell on the local host" +msgstr "Добијте приступ шкољци на локалном домаћину" + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:8 +msgid "Authentication is required to acquire a shell on the local host." +msgstr "" +"Потребно је да се идентификујете да бисте добили приступ шкољци на локалном " +"домаћину." + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:9 +msgid "Acquire a pseudo TTY in a local container" +msgstr "Добијте приступ псеудо писаћој машини унутар локалног контејнера" + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:10 +msgid "" +"Authentication is required to acquire a pseudo TTY in a local container." +msgstr "" +"Потребно је да се идентификујете да бисте добили приступ псеудо писаћој " +"машини унутар локалног контејнера." + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:11 +msgid "Acquire a pseudo TTY on the local host" +msgstr "Добијте приступ псеудо писаћој машини на локалном домаћину" + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:12 +msgid "Authentication is required to acquire a pseudo TTY on the local host." +msgstr "" +"Потребно је да се идентификујете да бисте добили приступ псеудо писаћој " +"машини на локалном домаћину." + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:13 +msgid "Manage local virtual machines and containers" +msgstr "Управљајте локалним виртуелним машинама и контејнерима" + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:14 +msgid "" +"Authentication is required to manage local virtual machines and containers." +msgstr "" +"Потребно је да се идентификујете да бисте управљали локалним виртуелним " +"машинама и контејнерима." + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:15 +msgid "Manage local virtual machine and container images" +msgstr "Управљајте локалним виртуелним машинама и сликама контејнера" + +#: ../src/machine/org.freedesktop.machine1.policy.in.h:16 +msgid "" +"Authentication is required to manage local virtual machine and container " +"images." +msgstr "" +"Потребно је да се идентификујете да бисте управљали локалним виртуелним " +"машинама и сликама контејнера." + +#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1 +msgid "Set system time" +msgstr "Поставите системско време" + +#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:2 +msgid "Authentication is required to set the system time." +msgstr "Потребно је да се идентификујете да бисте поставили системско време." + +#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:3 +msgid "Set system timezone" +msgstr "Поставите системску временску зону" + +#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:4 +msgid "Authentication is required to set the system timezone." +msgstr "" +"Потребно је да се идентификујете да бисте поставили системску временску зону." + +#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:5 +msgid "Set RTC to local timezone or UTC" +msgstr "Поставите RTC на локалну временску зону или UTC зону" + +#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:6 +msgid "" +"Authentication is required to control whether the RTC stores the local or " +"UTC time." +msgstr "" +"Потребно је да се идентификујете да бисте подесили да ли RTC чува локално " +"или UTC време." + +#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:7 +msgid "Turn network time synchronization on or off" +msgstr "Укључите или искључите усклађивање времена са мреже" + +#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:8 +msgid "" +"Authentication is required to control whether network time synchronization " +"shall be enabled." +msgstr "" +"Потребно је да се идентификујете да бисте подесили да ли се време усклађује " +"са мреже." + +#: ../src/core/dbus-unit.c:428 +msgid "Authentication is required to start '$(unit)'." +msgstr "Потребно је да се идентификујете да бисте покренули „$(unit)“." + +#: ../src/core/dbus-unit.c:429 +msgid "Authentication is required to stop '$(unit)'." +msgstr "Потребно је да се идентификујете да бисте зауставили „$(unit)“." + +#: ../src/core/dbus-unit.c:430 +msgid "Authentication is required to reload '$(unit)'." +msgstr "Потребно је да се идентификујете да бисте поново учитали „$(unit)“." + +#: ../src/core/dbus-unit.c:431 ../src/core/dbus-unit.c:432 +msgid "Authentication is required to restart '$(unit)'." +msgstr "Потребно је да се идентификујете да бисте поново покренули „$(unit)“." + +#: ../src/core/dbus-unit.c:535 +msgid "Authentication is required to kill '$(unit)'." +msgstr "Потребно је да се идентификујете да бисте убили „$(unit)“." + +#: ../src/core/dbus-unit.c:565 +msgid "Authentication is required to reset the \"failed\" state of '$(unit)'." +msgstr "" +"Потребно је да се идентификујете да бисте поново поставили „неуспешно“ стање " +"за „$(unit)“." + +#: ../src/core/dbus-unit.c:597 +msgid "Authentication is required to set properties on '$(unit)'." +msgstr "" +"Потребно је да се идентификујете да бисте поставили својства за „$(unit)“." diff --git a/src/basic/missing.h b/src/basic/missing.h index 9811b6b23e..1e3af283bb 100644 --- a/src/basic/missing.h +++ b/src/basic/missing.h @@ -842,6 +842,19 @@ static inline int setns(int fd, int nstype) { #define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1) #endif +#if !HAVE_DECL_IFLA_BR_PRIORITY +#define IFLA_BR_UNSPEC 0 +#define IFLA_BR_FORWARD_DELAY 1 +#define IFLA_BR_HELLO_TIME 2 +#define IFLA_BR_MAX_AGE 3 +#define IFLA_BR_AGEING_TIME 4 +#define IFLA_BR_STP_STATE 5 +#define IFLA_BR_PRIORITY 6 +#define __IFLA_BR_MAX 7 + +#define IFLA_BR_MAX (__IFLA_BR_MAX - 1) +#endif + #if !HAVE_DECL_IFLA_BRPORT_LEARNING_SYNC #define IFLA_BRPORT_UNSPEC 0 #define IFLA_BRPORT_STATE 1 diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index 287e0dfa13..22ee6ad83f 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -607,27 +607,6 @@ int vt_disallocate(const char *name) { return 0; } -void warn_melody(void) { - _cleanup_close_ int fd = -1; - - fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY); - if (fd < 0) - return; - - /* Yeah, this is synchronous. Kinda sucks. But well... */ - - (void) ioctl(fd, KIOCSOUND, (int)(1193180/440)); - usleep(125*USEC_PER_MSEC); - - (void) ioctl(fd, KIOCSOUND, (int)(1193180/220)); - usleep(125*USEC_PER_MSEC); - - (void) ioctl(fd, KIOCSOUND, (int)(1193180/220)); - usleep(125*USEC_PER_MSEC); - - (void) ioctl(fd, KIOCSOUND, 0); -} - int make_console_stdio(void) { int fd, r; diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index a9e325ccb3..da2a5b8897 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -67,8 +67,6 @@ bool tty_is_console(const char *tty) _pure_; int vtnr_from_tty(const char *tty); const char *default_term_for_tty(const char *tty); -void warn_melody(void); - int make_stdio(int fd); int make_null_stdio(void); int make_console_stdio(void); diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c index 5354bf6e51..c920ef7626 100644 --- a/src/journal-remote/journal-remote.c +++ b/src/journal-remote/journal-remote.c @@ -954,7 +954,7 @@ static int remoteserver_init(RemoteServer *s, } if (s->active == 0) { - log_error("Zarro sources specified"); + log_error("Zero sources specified"); return -EINVAL; } diff --git a/src/libsystemd-network/lldp-internal.c b/src/libsystemd-network/lldp-internal.c index 3c04898e92..4012cd483b 100644 --- a/src/libsystemd-network/lldp-internal.c +++ b/src/libsystemd-network/lldp-internal.c @@ -21,6 +21,7 @@ ***/ #include "lldp-internal.h" +#include "sd-lldp.h" /* We store maximum 1K chassis entries */ #define LLDP_MIB_MAX_CHASSIS 1024 @@ -28,207 +29,6 @@ /* Maximum Ports can be attached to any chassis */ #define LLDP_MIB_MAX_PORT_PER_CHASSIS 32 -int lldp_read_chassis_id(tlv_packet *tlv, - uint8_t *type, - uint16_t *length, - uint8_t **data) { - uint8_t subtype; - int r; - - assert_return(tlv, -EINVAL); - - r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_CHASSIS_ID); - if (r < 0) - goto out2; - - r = tlv_packet_read_u8(tlv, &subtype); - if (r < 0) - goto out1; - - switch (subtype) { - case LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS: - - r = tlv_packet_read_bytes(tlv, data, length); - if (r < 0) - goto out1; - - break; - default: - r = -EOPNOTSUPP; - break; - } - - *type = subtype; - - out1: - (void) lldp_tlv_packet_exit_container(tlv); - - out2: - return r; -} - -int lldp_read_port_id(tlv_packet *tlv, - uint8_t *type, - uint16_t *length, - uint8_t **data) { - uint8_t subtype; - char *s; - int r; - - assert_return(tlv, -EINVAL); - - r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_PORT_ID); - if (r < 0) - goto out2; - - r = tlv_packet_read_u8(tlv, &subtype); - if (r < 0) - goto out1; - - switch (subtype) { - case LLDP_PORT_SUBTYPE_PORT_COMPONENT: - case LLDP_PORT_SUBTYPE_INTERFACE_ALIAS: - case LLDP_PORT_SUBTYPE_INTERFACE_NAME: - case LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED: - - r = tlv_packet_read_string(tlv, &s, length); - if (r < 0) - goto out1; - - *data = (uint8_t *) s; - - break; - case LLDP_PORT_SUBTYPE_MAC_ADDRESS: - - r = tlv_packet_read_bytes(tlv, data, length); - if (r < 0) - goto out1; - - break; - default: - r = -EOPNOTSUPP; - break; - } - - *type = subtype; - - out1: - (void) lldp_tlv_packet_exit_container(tlv); - - out2: - return r; -} - -int lldp_read_ttl(tlv_packet *tlv, uint16_t *ttl) { - int r; - - assert_return(tlv, -EINVAL); - - r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_TTL); - if (r < 0) - goto out; - - r = tlv_packet_read_u16(tlv, ttl); - - (void) lldp_tlv_packet_exit_container(tlv); - - out: - return r; -} - -int lldp_read_system_name(tlv_packet *tlv, - uint16_t *length, - char **data) { - char *s; - int r; - - assert_return(tlv, -EINVAL); - - r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_SYSTEM_NAME); - if (r < 0) - return r; - - r = tlv_packet_read_string(tlv, &s, length); - if (r < 0) - goto out; - - *data = (char *) s; - - out: - (void) lldp_tlv_packet_exit_container(tlv); - - return r; -} - -int lldp_read_system_description(tlv_packet *tlv, - uint16_t *length, - char **data) { - char *s; - int r; - - assert_return(tlv, -EINVAL); - - r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_SYSTEM_DESCRIPTION); - if (r < 0) - return r; - - r = tlv_packet_read_string(tlv, &s, length); - if (r < 0) - goto out; - - *data = (char *) s; - - out: - (void) lldp_tlv_packet_exit_container(tlv); - - return r; -} - -int lldp_read_port_description(tlv_packet *tlv, - uint16_t *length, - char **data) { - char *s; - int r; - - assert_return(tlv, -EINVAL); - - r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_PORT_DESCRIPTION); - if (r < 0) - return r; - - r = tlv_packet_read_string(tlv, &s, length); - if (r < 0) - goto out; - - *data = (char *) s; - - out: - (void) lldp_tlv_packet_exit_container(tlv); - - return r; -} - -int lldp_read_system_capability(tlv_packet *tlv, uint16_t *data) { - int r; - - assert_return(tlv, -EINVAL); - - r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_SYSTEM_CAPABILITIES); - if (r < 0) - return r; - - r = tlv_packet_read_u16(tlv, data); - if (r < 0) - goto out; - - return 0; - out: - - (void) lldp_tlv_packet_exit_container(tlv); - - return r; -} - /* 10.5.5.2.2 mibUpdateObjects () * The mibUpdateObjects () procedure updates the MIB objects corresponding to * the TLVs contained in the received LLDPDU for the LLDP remote system @@ -244,7 +44,7 @@ int lldp_mib_update_objects(lldp_chassis *c, tlv_packet *tlv) { assert_return(c, -EINVAL); assert_return(tlv, -EINVAL); - r = lldp_read_port_id(tlv, &type, &length, &data); + r = sd_lldp_packet_read_port_id(tlv, &type, &data, &length); if (r < 0) return r; @@ -253,13 +53,13 @@ int lldp_mib_update_objects(lldp_chassis *c, tlv_packet *tlv) { if ((p->type == type && p->length == length && !memcmp(p->data, data, p->length))) { - r = lldp_read_ttl(tlv, &ttl); + r = sd_lldp_packet_read_ttl(tlv, &ttl); if (r < 0) return r; p->until = ttl * USEC_PER_SEC + now(clock_boottime_or_monotonic()); - tlv_packet_free(p->packet); + sd_lldp_packet_unref(p->packet); p->packet = tlv; prioq_reshuffle(p->c->by_expiry, p, &p->prioq_idx); @@ -281,7 +81,7 @@ int lldp_mib_remove_objects(lldp_chassis *c, tlv_packet *tlv) { assert_return(c, -EINVAL); assert_return(tlv, -EINVAL); - r = lldp_read_port_id(tlv, &type, &length, &data); + r = sd_lldp_packet_read_port_id(tlv, &type, &data, &length); if (r < 0) return r; @@ -312,11 +112,11 @@ int lldp_mib_add_objects(Prioq *by_expiry, assert_return(neighbour_mib, -EINVAL); assert_return(tlv, -EINVAL); - r = lldp_read_chassis_id(tlv, &subtype, &length, &data); + r = sd_lldp_packet_read_chassis_id(tlv, &subtype, &data, &length); if (r < 0) goto drop; - r = lldp_read_ttl(tlv, &ttl); + r = sd_lldp_packet_read_ttl(tlv, &ttl); if (r < 0) goto drop; @@ -401,7 +201,7 @@ int lldp_mib_add_objects(Prioq *by_expiry, return 0; drop: - tlv_packet_free(tlv); + sd_lldp_packet_unref(tlv); if (new_chassis) hashmap_remove(neighbour_mib, &c->chassis_id); @@ -435,7 +235,7 @@ void lldp_neighbour_port_free(lldp_neighbour_port *p) { if(!p) return; - tlv_packet_free(p->packet); + sd_lldp_packet_unref(p->packet); free(p->data); free(p); @@ -452,11 +252,11 @@ int lldp_neighbour_port_new(lldp_chassis *c, assert(tlv); - r = lldp_read_port_id(tlv, &type, &length, &data); + r = sd_lldp_packet_read_port_id(tlv, &type, &data, &length); if (r < 0) return r; - r = lldp_read_ttl(tlv, &ttl); + r = sd_lldp_packet_read_ttl(tlv, &ttl); if (r < 0) return r; @@ -505,7 +305,7 @@ int lldp_chassis_new(tlv_packet *tlv, assert(tlv); - r = lldp_read_chassis_id(tlv, &type, &length, &data); + r = sd_lldp_packet_read_chassis_id(tlv, &type, &data, &length); if (r < 0) return r; @@ -531,3 +331,30 @@ int lldp_chassis_new(tlv_packet *tlv, return 0; } + +int lldp_receive_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) { + _cleanup_lldp_packet_unref_ tlv_packet *packet = NULL; + tlv_packet *p; + uint16_t length; + int r; + + assert(fd); + assert(userdata); + + r = tlv_packet_new(&packet); + if (r < 0) + return r; + + length = read(fd, &packet->pdu, sizeof(packet->pdu)); + + /* Silently drop the packet */ + if ((size_t) length > ETHER_MAX_LEN) + return 0; + + packet->userdata = userdata; + + p = packet; + packet = NULL; + + return lldp_handle_packet(p, (uint16_t) length); +} diff --git a/src/libsystemd-network/lldp-internal.h b/src/libsystemd-network/lldp-internal.h index f4eadbb87e..284cc6720e 100644 --- a/src/libsystemd-network/lldp-internal.h +++ b/src/libsystemd-network/lldp-internal.h @@ -26,6 +26,7 @@ #include "list.h" #include "lldp-tlv.h" #include "prioq.h" +#include "sd-event.h" typedef struct lldp_neighbour_port lldp_neighbour_port; typedef struct lldp_chassis lldp_chassis; @@ -86,13 +87,6 @@ int lldp_mib_update_objects(lldp_chassis *c, tlv_packet *tlv); int lldp_mib_add_objects(Prioq *by_expiry, Hashmap *neighbour_mib, tlv_packet *tlv); int lldp_mib_remove_objects(lldp_chassis *c, tlv_packet *tlv); -int lldp_read_chassis_id(tlv_packet *tlv, uint8_t *type, uint16_t *length, uint8_t **data); -int lldp_read_port_id(tlv_packet *tlv, uint8_t *type, uint16_t *length, uint8_t **data); -int lldp_read_ttl(tlv_packet *tlv, uint16_t *ttl); -int lldp_read_system_name(tlv_packet *tlv, uint16_t *length, char **data); -int lldp_read_system_description(tlv_packet *tlv, uint16_t *length, char **data); -int lldp_read_system_capability(tlv_packet *tlv, uint16_t *data); -int lldp_read_port_description(tlv_packet *tlv, uint16_t *length, char **data); - int lldp_handle_packet(tlv_packet *m, uint16_t length); +int lldp_receive_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata); #define log_lldp(fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__) diff --git a/src/libsystemd-network/lldp-network.c b/src/libsystemd-network/lldp-network.c index 664d2f7867..12a6599ff1 100644 --- a/src/libsystemd-network/lldp-network.c +++ b/src/libsystemd-network/lldp-network.c @@ -82,30 +82,3 @@ int lldp_network_bind_raw_socket(int ifindex) { return r; } - -int lldp_receive_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) { - _cleanup_tlv_packet_free_ tlv_packet *packet = NULL; - tlv_packet *p; - uint16_t length; - int r; - - assert(fd); - assert(userdata); - - r = tlv_packet_new(&packet); - if (r < 0) - return r; - - length = read(fd, &packet->pdu, sizeof(packet->pdu)); - - /* Silently drop the packet */ - if ((size_t) length > ETHER_MAX_LEN) - return 0; - - packet->userdata = userdata; - - p = packet; - packet = NULL; - - return lldp_handle_packet(p, (uint16_t) length); -} diff --git a/src/libsystemd-network/lldp-network.h b/src/libsystemd-network/lldp-network.h index b7f8d3bf80..74ee13a414 100644 --- a/src/libsystemd-network/lldp-network.h +++ b/src/libsystemd-network/lldp-network.h @@ -25,4 +25,3 @@ #include "sd-event.h" int lldp_network_bind_raw_socket(int ifindex); -int lldp_receive_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata); diff --git a/src/libsystemd-network/lldp-port.c b/src/libsystemd-network/lldp-port.c index 97fe7c1dd3..7486b4c38f 100644 --- a/src/libsystemd-network/lldp-port.c +++ b/src/libsystemd-network/lldp-port.c @@ -23,6 +23,7 @@ #include "async.h" #include "lldp-port.h" #include "lldp-network.h" +#include "lldp-internal.h" int lldp_port_start(lldp_port *p) { int r; diff --git a/src/libsystemd-network/lldp-tlv.c b/src/libsystemd-network/lldp-tlv.c index 0cea5b10a6..66af22e37d 100644 --- a/src/libsystemd-network/lldp-tlv.c +++ b/src/libsystemd-network/lldp-tlv.c @@ -54,22 +54,41 @@ int tlv_packet_new(tlv_packet **ret) { return -ENOMEM; LIST_HEAD_INIT(m->sections); + m->n_ref = 1; *ret = m; return 0; } -void tlv_packet_free(tlv_packet *m) { +tlv_packet *sd_lldp_packet_ref(tlv_packet *m) { + + if (!m) + return NULL; + + assert(m->n_ref > 0); + m->n_ref++; + + return m; +} + +tlv_packet *sd_lldp_packet_unref(tlv_packet *m) { tlv_section *s, *n; if (!m) - return; + return NULL; + + assert(m->n_ref > 0); + m->n_ref--; + + if (m->n_ref > 0) + return m; LIST_FOREACH_SAFE(section, s, n, m->sections) tlv_section_free(s); free(m); + return NULL; } int tlv_packet_append_bytes(tlv_packet *m, const void *data, size_t data_length) { @@ -221,9 +240,9 @@ int tlv_packet_read_string(tlv_packet *m, char **data, uint16_t *data_length) { return r; *data = (char *) val; - *data_length = m->container->length; + *data_length = m->container->data + m->container->length - m->container->read_pos; - m->container->read_pos += m->container->length; + m->container->read_pos += *data_length; return 0; } @@ -239,9 +258,9 @@ int tlv_packet_read_bytes(tlv_packet *m, uint8_t **data, uint16_t *data_length) return r; *data = (uint8_t *) val; - *data_length = m->container->length; + *data_length = m->container->data + m->container->length - m->container->read_pos; - m->container->read_pos += m->container->length; + m->container->read_pos += *data_length; return 0; } @@ -258,7 +277,7 @@ int tlv_packet_parse_pdu(tlv_packet *m, uint16_t size) { p = m->pdu; - /* extract ethernet herader */ + /* extract ethernet header */ memcpy(&m->mac, p, ETH_ALEN); p += sizeof(struct ether_header); @@ -278,6 +297,17 @@ int tlv_packet_parse_pdu(tlv_packet *m, uint16_t size) { } p += 2; + + if (section->type == LLDP_TYPE_PRIVATE && + section->length >= LLDP_OUI_LEN + 1) { + section->oui = p; + p += LLDP_OUI_LEN; + section->subtype = *p++; + + section->length -= LLDP_OUI_LEN + 1; + l += LLDP_OUI_LEN + 1; + } + section->data = p; LIST_FIND_TAIL(section, m->sections, tail); @@ -294,6 +324,7 @@ int lldp_tlv_packet_enter_container(tlv_packet *m, uint16_t type) { tlv_section *s; assert_return(m, -EINVAL); + assert_return(type != LLDP_TYPE_PRIVATE, -EINVAL); LIST_FOREACH(section, s, m->sections) if (s->type == type) @@ -305,7 +336,35 @@ int lldp_tlv_packet_enter_container(tlv_packet *m, uint16_t type) { m->container->read_pos = s->data; if (!m->container->read_pos) { - m->container = 0; + m->container = NULL; + return -1; + } + + return 0; +} + +int lldp_tlv_packet_enter_container_oui(tlv_packet *m, const uint8_t *oui, uint8_t subtype) { + tlv_section *s; + + assert_return(m, -EINVAL); + assert_return(oui, -EINVAL); + + LIST_FOREACH(section, s, m->sections) { + if (s->type == LLDP_TYPE_PRIVATE && + s->oui && + s->subtype == subtype && + !memcmp(s->oui, oui, LLDP_OUI_LEN)) + break; + } + + if (!s) + return -1; + + m->container = s; + + m->container->read_pos = s->data; + if (!m->container->read_pos) { + m->container = NULL; return -1; } @@ -319,3 +378,270 @@ int lldp_tlv_packet_exit_container(tlv_packet *m) { return 0; } + +static int lldp_tlv_packet_read_u16_tlv(tlv_packet *tlv, uint16_t type, uint16_t *value) { + int r, r2; + + assert_return(tlv, -EINVAL); + + r = lldp_tlv_packet_enter_container(tlv, type); + if (r < 0) + goto out; + + r = tlv_packet_read_u16(tlv, value); + r2 = lldp_tlv_packet_exit_container(tlv); + + out: + return r < 0 ? r : r2; +} + +static int lldp_tlv_packet_read_string_tlv(tlv_packet *tlv, uint16_t type, char **data, uint16_t *length) { + char *s; + int r, r2; + + assert_return(tlv, -EINVAL); + + r = lldp_tlv_packet_enter_container(tlv, type); + if (r < 0) + return r; + + r = tlv_packet_read_string(tlv, &s, length); + if (r < 0) + goto out; + + *data = (char *) s; + + out: + r2 = lldp_tlv_packet_exit_container(tlv); + + return r < 0 ? r : r2; +} + +int sd_lldp_packet_read_chassis_id(tlv_packet *tlv, + uint8_t *type, + uint8_t **data, + uint16_t *length) { + uint8_t subtype; + int r, r2; + + assert_return(tlv, -EINVAL); + + r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_CHASSIS_ID); + if (r < 0) + goto out2; + + r = tlv_packet_read_u8(tlv, &subtype); + if (r < 0) + goto out1; + + switch (subtype) { + case LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS: + + r = tlv_packet_read_bytes(tlv, data, length); + if (r < 0) + goto out1; + + break; + default: + r = -EOPNOTSUPP; + break; + } + + *type = subtype; + + out1: + r2 = lldp_tlv_packet_exit_container(tlv); + + out2: + return r < 0 ? r : r2; +} + +int sd_lldp_packet_read_port_id(tlv_packet *tlv, + uint8_t *type, + uint8_t **data, + uint16_t *length) { + uint8_t subtype; + char *s; + int r, r2; + + assert_return(tlv, -EINVAL); + + r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_PORT_ID); + if (r < 0) + goto out2; + + r = tlv_packet_read_u8(tlv, &subtype); + if (r < 0) + goto out1; + + switch (subtype) { + case LLDP_PORT_SUBTYPE_PORT_COMPONENT: + case LLDP_PORT_SUBTYPE_INTERFACE_ALIAS: + case LLDP_PORT_SUBTYPE_INTERFACE_NAME: + case LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED: + + r = tlv_packet_read_string(tlv, &s, length); + if (r < 0) + goto out1; + + *data = (uint8_t *) s; + + break; + case LLDP_PORT_SUBTYPE_MAC_ADDRESS: + + r = tlv_packet_read_bytes(tlv, data, length); + if (r < 0) + goto out1; + + break; + default: + r = -EOPNOTSUPP; + break; + } + + *type = subtype; + + out1: + r2 = lldp_tlv_packet_exit_container(tlv); + + out2: + return r < 0 ? r : r2; +} + +int sd_lldp_packet_read_ttl(tlv_packet *tlv, uint16_t *ttl) { + return lldp_tlv_packet_read_u16_tlv(tlv, LLDP_TYPE_TTL, ttl); +} + +int sd_lldp_packet_read_system_name(tlv_packet *tlv, + char **data, + uint16_t *length) { + return lldp_tlv_packet_read_string_tlv(tlv, LLDP_TYPE_SYSTEM_NAME, data, length); +} + +int sd_lldp_packet_read_system_description(tlv_packet *tlv, + char **data, + uint16_t *length) { + return lldp_tlv_packet_read_string_tlv(tlv, LLDP_TYPE_SYSTEM_DESCRIPTION, data, length); +} + +int sd_lldp_packet_read_port_description(tlv_packet *tlv, + char **data, + uint16_t *length) { + return lldp_tlv_packet_read_string_tlv(tlv, LLDP_TYPE_PORT_DESCRIPTION, data, length); +} + +int sd_lldp_packet_read_system_capability(tlv_packet *tlv, uint16_t *data) { + return lldp_tlv_packet_read_u16_tlv(tlv, LLDP_TYPE_SYSTEM_CAPABILITIES, data); +} + +int sd_lldp_packet_read_port_vlan_id(tlv_packet *tlv, uint16_t *id) { + int r, r2; + + assert_return(tlv, -EINVAL); + + r = lldp_tlv_packet_enter_container_oui(tlv, LLDP_OUI_802_1, LLDP_OUI_SUBTYPE_802_1_PORT_VLAN_ID); + if (r < 0) + goto out; + + r = tlv_packet_read_u16(tlv, id); + r2 = lldp_tlv_packet_exit_container(tlv); + + out: + return r < 0 ? r : r2; +} + +int sd_lldp_packet_read_port_protocol_vlan_id(sd_lldp_packet *tlv, uint8_t *flags, uint16_t *id) { + int r, r2; + + assert_return(tlv, -EINVAL); + + r = lldp_tlv_packet_enter_container_oui(tlv, LLDP_OUI_802_1, LLDP_OUI_SUBTYPE_802_1_PORT_PROTOCOL_VLAN_ID); + if (r < 0) + goto out; + + r = tlv_packet_read_u8(tlv, flags); + if (r >= 0) + r = tlv_packet_read_u16(tlv, id); + + r2 = lldp_tlv_packet_exit_container(tlv); + + out: + return r < 0 ? r : r2; +} + +int sd_lldp_packet_read_vlan_name(tlv_packet *tlv, uint16_t *vlan_id, char **name, uint16_t *length) { + int r, r2; + uint8_t len = 0; + + assert_return(tlv, -EINVAL); + + r = lldp_tlv_packet_enter_container_oui(tlv, LLDP_OUI_802_1, LLDP_OUI_SUBTYPE_802_1_VLAN_NAME); + if (r < 0) + goto out; + + r = tlv_packet_read_u16(tlv, vlan_id); + if (r >= 0) + r = tlv_packet_read_u8(tlv, &len); + if (r >= 0) + r = tlv_packet_read_string(tlv, name, length); + + if (r >= 0 && len < *length) + *length = len; + + r2 = lldp_tlv_packet_exit_container(tlv); + + out: + return r < 0 ? r : r2; +} + +int sd_lldp_packet_read_management_vid(tlv_packet *tlv, uint16_t *id) { + int r, r2; + + assert_return(tlv, -EINVAL); + + r = lldp_tlv_packet_enter_container_oui(tlv, LLDP_OUI_802_1, LLDP_OUI_SUBTYPE_802_1_MANAGEMENT_VID); + if (r < 0) + goto out; + + r = tlv_packet_read_u16(tlv, id); + r2 = lldp_tlv_packet_exit_container(tlv); + + out: + return r < 0 ? r : r2; +} + +int sd_lldp_packet_read_link_aggregation(sd_lldp_packet *tlv, uint8_t *status, uint32_t *id) { + int r, r2; + + assert_return(tlv, -EINVAL); + + r = lldp_tlv_packet_enter_container_oui(tlv, LLDP_OUI_802_1, LLDP_OUI_SUBTYPE_802_1_LINK_AGGREGATION); + if (r < 0) + goto out; + + r = tlv_packet_read_u8(tlv, status); + if (r >= 0) + r = tlv_packet_read_u32(tlv, id); + + r2 = lldp_tlv_packet_exit_container(tlv); + + out: + return r < 0 ? r : r2; +} + +int sd_lldp_packet_get_destination_type(tlv_packet *tlv, int *dest) { + assert_return(tlv, -EINVAL); + assert_return(dest, -EINVAL); + + /* 802.1AB-2009, Table 7-1 */ + if (!memcmp(&tlv->mac, LLDP_MAC_NEAREST_BRIDGE, ETH_ALEN)) + *dest = SD_LLDP_DESTINATION_TYPE_NEAREST_BRIDGE; + else if (!memcmp(&tlv->mac, LLDP_MAC_NEAREST_NON_TPMR_BRIDGE, ETH_ALEN)) + *dest = SD_LLDP_DESTINATION_TYPE_NEAREST_NON_TPMR_BRIDGE; + else if (!memcmp(&tlv->mac, LLDP_MAC_NEAREST_CUSTOMER_BRIDGE, ETH_ALEN)) + *dest = SD_LLDP_DESTINATION_TYPE_NEAREST_CUSTOMER_BRIDGE; + else + return -EINVAL; + + return 0; +} diff --git a/src/libsystemd-network/lldp-tlv.h b/src/libsystemd-network/lldp-tlv.h index ce3334e115..2d2c776be6 100644 --- a/src/libsystemd-network/lldp-tlv.h +++ b/src/libsystemd-network/lldp-tlv.h @@ -28,12 +28,18 @@ #include "lldp.h" #include "list.h" +#include "sd-lldp.h" + typedef struct tlv_packet tlv_packet; typedef struct tlv_section tlv_section; +#define LLDP_OUI_LEN 3 + struct tlv_section { uint16_t type; uint16_t length; + uint8_t *oui; + uint8_t subtype; uint8_t *read_pos; uint8_t *data; @@ -41,10 +47,16 @@ struct tlv_section { LIST_FIELDS(tlv_section, section); }; +#define LLDP_MAC_NEAREST_BRIDGE (uint8_t[]) { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e } +#define LLDP_MAC_NEAREST_NON_TPMR_BRIDGE (uint8_t[]) { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 } +#define LLDP_MAC_NEAREST_CUSTOMER_BRIDGE (uint8_t[]) { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 } + int tlv_section_new(tlv_section **ret); void tlv_section_free(tlv_section *ret); struct tlv_packet { + unsigned n_ref; + uint16_t type; uint16_t length; usec_t ts; @@ -61,10 +73,9 @@ struct tlv_packet { }; int tlv_packet_new(tlv_packet **ret); -void tlv_packet_free(tlv_packet *m); -DEFINE_TRIVIAL_CLEANUP_FUNC(tlv_packet*, tlv_packet_free); -#define _cleanup_tlv_packet_free_ _cleanup_(tlv_packet_freep) +DEFINE_TRIVIAL_CLEANUP_FUNC(sd_lldp_packet*, sd_lldp_packet_unref); +#define _cleanup_lldp_packet_unref_ _cleanup_(sd_lldp_packet_unrefp) int lldp_tlv_packet_open_container(tlv_packet *m, uint16_t type); int lldp_tlv_packet_close_container(tlv_packet *m); @@ -76,6 +87,7 @@ int tlv_packet_append_u32(tlv_packet *m, uint32_t data); int tlv_packet_append_string(tlv_packet *m, char *data, uint16_t size); int lldp_tlv_packet_enter_container(tlv_packet *m, uint16_t type); +int lldp_tlv_packet_enter_container_oui(tlv_packet *m, const uint8_t *oui, uint8_t subtype); int lldp_tlv_packet_exit_container(tlv_packet *m); int tlv_packet_read_bytes(tlv_packet *m, uint8_t **data, uint16_t *data_length); diff --git a/src/libsystemd-network/lldp.h b/src/libsystemd-network/lldp.h index 5e4b283e26..19e5cc5f41 100644 --- a/src/libsystemd-network/lldp.h +++ b/src/libsystemd-network/lldp.h @@ -113,3 +113,16 @@ typedef enum LLDPMedCapability { LLDP_MED_CAPABILITY_MAX, LLDP_MED_CAPABILITY_INVALID = -1, } LLDPMedCapability; + +#define LLDP_OUI_802_1 (uint8_t[]) { 0x00, 0x80, 0xc2 } +#define LLDP_OUI_802_3 (uint8_t[]) { 0x00, 0x12, 0x0f } + +enum { + LLDP_OUI_SUBTYPE_802_1_PORT_VLAN_ID = 1, + LLDP_OUI_SUBTYPE_802_1_PORT_PROTOCOL_VLAN_ID = 2, + LLDP_OUI_SUBTYPE_802_1_VLAN_NAME = 3, + LLDP_OUI_SUBTYPE_802_1_PROTOCOL_IDENTITY = 4, + LLDP_OUI_SUBTYPE_802_1_VID_USAGE_DIGEST = 5, + LLDP_OUI_SUBTYPE_802_1_MANAGEMENT_VID = 6, + LLDP_OUI_SUBTYPE_802_1_LINK_AGGREGATION = 7, +}; diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c index 17512884f5..7aa405a655 100644 --- a/src/libsystemd-network/sd-lldp.c +++ b/src/libsystemd-network/sd-lldp.c @@ -199,7 +199,7 @@ int lldp_handle_packet(tlv_packet *tlv, uint16_t length) { goto out; } - /* skip type and lengh encoding */ + /* skip type and length encoding */ p += 2; q = p; @@ -338,7 +338,7 @@ int lldp_handle_packet(tlv_packet *tlv, uint16_t length) { lldp->statistics.stats_frames_in_errors_total ++; } - tlv_packet_free(tlv); + sd_lldp_packet_unref(tlv); return 0; } @@ -455,7 +455,7 @@ int sd_lldp_save(sd_lldp *lldp, const char *lldp_file) { _cleanup_free_ char *s = NULL; char *k, *t; - r = lldp_read_chassis_id(p->packet, &type, &length, &mac); + r = sd_lldp_packet_read_chassis_id(p->packet, &type, &mac, &length); if (r < 0) continue; @@ -468,7 +468,7 @@ int sd_lldp_save(sd_lldp *lldp, const char *lldp_file) { goto fail; } - r = lldp_read_port_id(p->packet, &type, &length, &port_id); + r = sd_lldp_packet_read_port_id(p->packet, &type, &port_id, &length); if (r < 0) continue; @@ -513,7 +513,7 @@ int sd_lldp_save(sd_lldp *lldp, const char *lldp_file) { free(s); s = k; - r = lldp_read_system_name(p->packet, &length, &k); + r = sd_lldp_packet_read_system_name(p->packet, &k, &length); if (r < 0) k = strappend(s, "'_NAME=N/A' "); else { @@ -535,7 +535,7 @@ int sd_lldp_save(sd_lldp *lldp, const char *lldp_file) { free(s); s = k; - (void) lldp_read_system_capability(p->packet, &data); + (void) sd_lldp_packet_read_system_capability(p->packet, &data); sprintf(buf, "'_CAP=%x'", data); @@ -702,3 +702,35 @@ int sd_lldp_new(int ifindex, return 0; } + +int sd_lldp_get_packets(sd_lldp *lldp, sd_lldp_packet ***tlvs) { + lldp_neighbour_port *p; + lldp_chassis *c; + Iterator iter; + unsigned count = 0, i; + + assert_return(lldp, -EINVAL); + assert_return(tlvs, -EINVAL); + + HASHMAP_FOREACH(c, lldp->neighbour_mib, iter) { + LIST_FOREACH(port, p, c->ports) + count++; + } + + if (!count) { + *tlvs = NULL; + return 0; + } + + *tlvs = new(sd_lldp_packet *, count); + if (!*tlvs) + return -ENOMEM; + + i = 0; + HASHMAP_FOREACH(c, lldp->neighbour_mib, iter) { + LIST_FOREACH(port, p, c->ports) + (*tlvs)[i++] = sd_lldp_packet_ref(p->packet); + } + + return count; +} diff --git a/src/libsystemd-network/test-lldp.c b/src/libsystemd-network/test-lldp.c index 06545aee59..e57102a576 100644 --- a/src/libsystemd-network/test-lldp.c +++ b/src/libsystemd-network/test-lldp.c @@ -25,20 +25,26 @@ #include <net/ethernet.h> #include <arpa/inet.h> +#include "sd-lldp.h" +#include "sd-event.h" +#include "event-util.h" #include "macro.h" #include "lldp.h" #include "lldp-tlv.h" +#include "lldp-network.h" #define TEST_LLDP_PORT "em1" #define TEST_LLDP_TYPE_SYSTEM_NAME "systemd-lldp" #define TEST_LLDP_TYPE_SYSTEM_DESC "systemd-lldp-desc" +static int test_fd[2]; + static struct ether_addr mac_addr = { .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'} }; static int lldp_build_tlv_packet(tlv_packet **ret) { - _cleanup_tlv_packet_free_ tlv_packet *m = NULL; + _cleanup_lldp_packet_unref_ tlv_packet *m = NULL; const uint8_t lldp_dst[] = LLDP_MULTICAST_ADDR; struct ether_header ether = { .ether_type = htons(ETHERTYPE_LLDP), @@ -202,6 +208,15 @@ static int lldp_parse_ttl_tlv(tlv_packet *m) { return 0; } +static int lldp_get_destination_type(tlv_packet *m) { + int dest; + + assert_se(sd_lldp_packet_get_destination_type(m, &dest) >= 0); + assert_se(dest == SD_LLDP_DESTINATION_TYPE_NEAREST_BRIDGE); + + return 0; +} + static int lldp_parse_tlv_packet(tlv_packet *m, int len) { uint8_t subtype; @@ -212,20 +227,241 @@ static int lldp_parse_tlv_packet(tlv_packet *m, int len) { assert_se(lldp_parse_ttl_tlv(m) >= 0); assert_se(lldp_parse_system_desc_tlv(m) >= 0); + assert_se(lldp_get_destination_type(m) >= 0); + return 0; } -int main(int argc, char *argv[]) { - _cleanup_tlv_packet_free_ tlv_packet *tlv = NULL; +static void test_parser(void) { + _cleanup_lldp_packet_unref_ tlv_packet *tlv = NULL; /* form a packet */ lldp_build_tlv_packet(&tlv); - /* parse the packet */ tlv_packet_parse_pdu(tlv, tlv->length); - /* verify */ lldp_parse_tlv_packet(tlv, tlv->length); +} + +int lldp_network_bind_raw_socket(int ifindex) { + if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, test_fd) < 0) + return -errno; + + return test_fd[0]; +} + +static int lldp_handler_calls; +static void lldp_handler (sd_lldp *lldp, int event, void *userdata) { + lldp_handler_calls++; +} + +static int start_lldp(sd_lldp **lldp, sd_event *e, sd_lldp_cb_t cb, void *cb_data) { + int r; + + r = sd_lldp_new(42, "dummy", &mac_addr, lldp); + if (r) + return r; + + r = sd_lldp_attach_event(*lldp, e, 0); + if (r) + return r; + + r = sd_lldp_set_callback(*lldp, cb, cb_data); + if (r) + return r; + + r = sd_lldp_start(*lldp); + if (r) + return r; + + return 0; +} + +static int stop_lldp(sd_lldp *lldp) { + int r; + + r = sd_lldp_stop(lldp); + if (r) + return r; + + r = sd_lldp_detach_event(lldp); + if (r) + return r; + + sd_lldp_free(lldp); + safe_close(test_fd[1]); + + return 0; +} + +static void test_receive_basic_packet(sd_event *e) { + sd_lldp *lldp; + sd_lldp_packet **packets; + uint8_t type, *data; + uint16_t length, ttl; + int dest_type; + char *str; + uint8_t frame[] = { + /* Ethernet header */ + 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, /* Destination MAC*/ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* Source MAC */ + 0x88, 0xcc, /* Ethertype */ + /* LLDP mandatory TLVs */ + 0x02, 0x07, 0x04, 0x00, 0x01, 0x02, /* Chassis: MAC, 00:01:02:03:04:05 */ + 0x03, 0x04, 0x05, + 0x04, 0x04, 0x05, 0x31, 0x2f, 0x33, /* Port: interface name, "1/3" */ + 0x06, 0x02, 0x00, 0x78, /* TTL: 120 seconds*/ + /* LLDP optional TLVs */ + 0x08, 0x04, 0x50, 0x6f, 0x72, 0x74, /* Port Description: "Port" */ + 0x0a, 0x03, 0x53, 0x59, 0x53, /* System Name: "SYS" */ + 0x0c, 0x04, 0x66, 0x6f, 0x6f, 0x00, /* System Description: "foo" (NULL-terminated) */ + 0x00, 0x00 /* End Of LLDPDU */ + }; + + lldp_handler_calls = 0; + assert_se(start_lldp(&lldp, e, lldp_handler, NULL) == 0); + + assert_se(write(test_fd[1], frame, sizeof(frame)) == sizeof(frame)); + sd_event_run(e, 0); + assert_se(lldp_handler_calls == 1); + assert_se(sd_lldp_get_packets(lldp, &packets) == 1); + + assert_se(sd_lldp_packet_read_chassis_id(packets[0], &type, &data, &length) == 0); + assert_se(type == LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS); + assert_se(length == ETH_ALEN); + assert_se(!memcmp(data, "\x00\x01\x02\x03\x04\x05", ETH_ALEN)); + + assert_se(sd_lldp_packet_read_port_id(packets[0], &type, &data, &length) == 0); + assert_se(type == LLDP_PORT_SUBTYPE_INTERFACE_NAME); + assert_se(length == 3); + assert_se(strneq((char *) data, "1/3", 3)); + + assert_se(sd_lldp_packet_read_port_description(packets[0], &str, &length) == 0); + assert_se(length == 4); + assert_se(strneq(str, "Port", 4)); + + assert_se(sd_lldp_packet_read_system_name(packets[0], &str, &length) == 0); + assert_se(length == 3); + assert_se(strneq(str, "SYS", 3)); + + assert_se(sd_lldp_packet_read_system_description(packets[0], &str, &length) == 0); + assert_se(length == 4); /* This is the real length in the TLV packet */ + assert_se(strneq(str, "foo", 3)); + + assert_se(sd_lldp_packet_read_ttl(packets[0], &ttl) == 0); + assert_se(ttl == 120); + + assert_se(sd_lldp_packet_get_destination_type(packets[0], &dest_type) == 0); + assert_se(dest_type == SD_LLDP_DESTINATION_TYPE_NEAREST_NON_TPMR_BRIDGE); + + sd_lldp_packet_unref(packets[0]); + free(packets); + + assert_se(stop_lldp(lldp) == 0); +} + +static void test_receive_incomplete_packet(sd_event *e) { + sd_lldp *lldp; + sd_lldp_packet **packets; + uint8_t frame[] = { + /* Ethernet header */ + 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, /* Destination MAC*/ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* Source MAC */ + 0x88, 0xcc, /* Ethertype */ + /* LLDP mandatory TLVs */ + 0x02, 0x07, 0x04, 0x00, 0x01, 0x02, /* Chassis: MAC, 00:01:02:03:04:05 */ + 0x03, 0x04, 0x05, + 0x04, 0x04, 0x05, 0x31, 0x2f, 0x33, /* Port: interface name, "1/3" */ + /* Missing TTL */ + 0x00, 0x00 /* End Of LLDPDU */ + }; + + lldp_handler_calls = 0; + assert_se(start_lldp(&lldp, e, lldp_handler, NULL) == 0); + + assert_se(write(test_fd[1], frame, sizeof(frame)) == sizeof(frame)); + sd_event_run(e, 0); + assert_se(lldp_handler_calls == 0); + assert_se(sd_lldp_get_packets(lldp, &packets) == 0); + + assert_se(stop_lldp(lldp) == 0); +} + +static void test_receive_oui_packet(sd_event *e) { + sd_lldp *lldp; + sd_lldp_packet **packets; + uint32_t id32; + uint16_t id16, len; + uint8_t flags; + char *str; + uint8_t frame[] = { + /* Ethernet header */ + 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, /* Destination MAC*/ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* Source MAC */ + 0x88, 0xcc, /* Ethertype */ + /* LLDP mandatory TLVs */ + 0x02, 0x07, 0x04, 0x00, 0x01, 0x02, /* Chassis: MAC, 00:01:02:03:04:05 */ + 0x03, 0x04, 0x05, + 0x04, 0x04, 0x05, 0x31, 0x2f, 0x33, /* Port TLV: interface name, "1/3" */ + 0x06, 0x02, 0x00, 0x78, /* TTL: 120 seconds*/ + /* LLDP optional TLVs */ + 0xfe, 0x06, 0x00, 0x80, 0xc2, 0x01, /* Port VLAN ID: 0x1234 */ + 0x12, 0x34, + 0xfe, 0x07, 0x00, 0x80, 0xc2, 0x02, /* Port and protocol: flag 1, PPVID 0x7788 */ + 0x01, 0x77, 0x88, + 0xfe, 0x0d, 0x00, 0x80, 0xc2, 0x03, /* VLAN Name: ID 0x1234, name "Vlan51" */ + 0x12, 0x34, 0x06, 0x56, 0x6c, 0x61, + 0x6e, 0x35, 0x31, + 0xfe, 0x06, 0x00, 0x80, 0xc2, 0x06, /* Management VID: 0x0102 */ + 0x01, 0x02, + 0xfe, 0x09, 0x00, 0x80, 0xc2, 0x07, /* Link aggregation: status 1, ID 0x00140012 */ + 0x01, 0x00, 0x14, 0x00, 0x12, + 0x00, 0x00 /* End of LLDPDU */ + }; + + lldp_handler_calls = 0; + assert_se(start_lldp(&lldp, e, lldp_handler, NULL) == 0); + + assert_se(write(test_fd[1], frame, sizeof(frame)) == sizeof(frame)); + sd_event_run(e, 0); + assert_se(lldp_handler_calls == 1); + assert_se(sd_lldp_get_packets(lldp, &packets) == 1); + + assert_se(sd_lldp_packet_read_port_vlan_id(packets[0], &id16) == 0); + assert_se(id16 == 0x1234); + + assert_se(sd_lldp_packet_read_port_protocol_vlan_id(packets[0], &flags, &id16) == 0); + assert_se(flags == 1); + assert_se(id16 == 0x7788); + + assert_se(sd_lldp_packet_read_vlan_name(packets[0], &id16, &str, &len) == 0); + assert_se(id16 == 0x1234); + assert_se(len == 6); + assert_se(strneq(str, "Vlan51", 6)); + + assert_se(sd_lldp_packet_read_management_vid(packets[0], &id16) == 0); + assert_se(id16 == 0x0102); + + assert_se(sd_lldp_packet_read_link_aggregation(packets[0], &flags, &id32) == 0); + assert_se(flags == 1); + assert_se(id32 == 0x00140012); + + sd_lldp_packet_unref(packets[0]); + free(packets); + + assert_se(stop_lldp(lldp) == 0); +} + +int main(int argc, char *argv[]) { + _cleanup_event_unref_ sd_event *e = NULL; + + test_parser(); + + /* LLDP reception tests */ + assert_se(sd_event_new(&e) == 0); + test_receive_basic_packet(e); + test_receive_incomplete_packet(e); + test_receive_oui_packet(e); return 0; } diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index 0d8e37b856..cf693de5fb 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -149,6 +149,15 @@ int sd_netlink_message_get_type(sd_netlink_message *m, uint16_t *type) { return 0; } +int sd_netlink_message_set_flags(sd_netlink_message *m, uint16_t flags) { + assert_return(m, -EINVAL); + assert_return(flags, -EINVAL); + + m->hdr->nlmsg_flags = flags; + + return 0; +} + int sd_netlink_message_is_broadcast(sd_netlink_message *m) { assert_return(m, -EINVAL); diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 2128329191..4a5340e659 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -97,7 +97,7 @@ static const NLType rtnl_link_info_data_macvlan_types[IFLA_MACVLAN_MAX + 1] = { [IFLA_MACVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 }, }; -static const NLType rtnl_link_info_data_bridge_types[IFLA_BRIDGE_MAX + 1] = { +static const NLType rtnl_link_bridge_management_types[IFLA_BRIDGE_MAX + 1] = { [IFLA_BRIDGE_FLAGS] = { .type = NETLINK_TYPE_U16 }, [IFLA_BRIDGE_MODE] = { .type = NETLINK_TYPE_U16 }, /* @@ -106,6 +106,15 @@ static const NLType rtnl_link_info_data_bridge_types[IFLA_BRIDGE_MAX + 1] = { */ }; +static const NLType rtnl_link_info_data_bridge_types[IFLA_BR_MAX + 1] = { + [IFLA_BR_FORWARD_DELAY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_HELLO_TIME] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_MAX_AGE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_AGEING_TIME] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_STP_STATE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_PRIORITY] = { .type = NETLINK_TYPE_U16 }, +}; + static const NLType rtnl_link_info_data_vlan_types[IFLA_VLAN_MAX + 1] = { [IFLA_VLAN_ID] = { .type = NETLINK_TYPE_U16 }, /* diff --git a/src/login/logind-action.c b/src/login/logind-action.c index f635fb1b63..a44e369149 100644 --- a/src/login/logind-action.c +++ b/src/login/logind-action.c @@ -147,7 +147,6 @@ int manager_handle_action( offending->uid, strna(u), offending->pid, strna(comm)); - warn_melody(); return -EPERM; } diff --git a/src/network/networkd-netdev-bridge.c b/src/network/networkd-netdev-bridge.c index fd6af7e99b..2eeb86a683 100644 --- a/src/network/networkd-netdev-bridge.c +++ b/src/network/networkd-netdev-bridge.c @@ -20,12 +20,96 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <net/if.h> #include "networkd-netdev-bridge.h" #include "missing.h" +#include "netlink-util.h" + +/* callback for brige netdev's parameter set */ +static int netdev_bridge_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { + _cleanup_netdev_unref_ NetDev *netdev = userdata; + int r; + + assert(netdev); + assert(m); + + r = sd_netlink_message_get_errno(m); + if (r < 0) { + log_netdev_warning_errno(netdev, r, "Bridge parameters could not be set: %m"); + return 1; + } + + log_netdev_debug(netdev, "Bridge parametres set success"); + + return 1; +} + +static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_message *m) { + _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL; + Bridge *b; + int r; + + assert(netdev); + + b = BRIDGE(netdev); + + assert(b); + + r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_NEWLINK, netdev->ifindex); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not allocate RTM_SETLINK message: %m"); + + r = sd_netlink_message_set_flags(req, NLM_F_REQUEST | NLM_F_ACK); + if (r < 0) + return log_link_error_errno(link, r, "Could not set netlink flags: %m"); + + r = sd_netlink_message_open_container(req, IFLA_LINKINFO); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_PROTINFO attribute: %m"); + + r = sd_netlink_message_open_container_union(req, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind)); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); + + if (b->forward_delay > 0) { + r = sd_netlink_message_append_u32(req, IFLA_BR_FORWARD_DELAY, b->forward_delay / USEC_PER_SEC); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_FORWARD_DELAY attribute: %m"); + } + + if (b->hello_time > 0) { + r = sd_netlink_message_append_u32(req, IFLA_BR_HELLO_TIME, b->hello_time / USEC_PER_SEC ); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_HELLO_TIME attribute: %m"); + } + + if (b->max_age > 0) { + r = sd_netlink_message_append_u32(req, IFLA_BR_MAX_AGE, b->max_age / USEC_PER_SEC); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_MAX_AGE attribute: %m"); + } + + r = sd_netlink_message_close_container(req); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m"); + + r = sd_netlink_message_close_container(req); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); + + r = sd_netlink_call_async(netdev->manager->rtnl, req, netdev_bridge_set_handler, netdev, 0, NULL); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m"); + + netdev_ref(netdev); + + return r; +} const NetDevVTable bridge_vtable = { .object_size = sizeof(Bridge), - .sections = "Match\0NetDev\0", + .sections = "Match\0NetDev\0Bridge\0", + .post_create = netdev_bridge_post_create, .create_type = NETDEV_CREATE_MASTER, }; diff --git a/src/network/networkd-netdev-bridge.h b/src/network/networkd-netdev-bridge.h index a7d02b1c91..d3bd15e0d6 100644 --- a/src/network/networkd-netdev-bridge.h +++ b/src/network/networkd-netdev-bridge.h @@ -27,6 +27,10 @@ typedef struct Bridge Bridge; struct Bridge { NetDev meta; + + usec_t forward_delay; + usec_t hello_time; + usec_t max_age; }; extern const NetDevVTable bridge_vtable; diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf index e0bd0e024a..4aac239850 100644 --- a/src/network/networkd-netdev-gperf.gperf +++ b/src/network/networkd-netdev-gperf.gperf @@ -86,3 +86,6 @@ Bond.UpDelaySec, config_parse_sec, 0, Bond.DownDelaySec, config_parse_sec, 0, offsetof(Bond, downdelay) Bond.ARPIntervalSec, config_parse_sec, 0, offsetof(Bond, arp_interval) Bond.LearnPacketIntervalSec, config_parse_sec, 0, offsetof(Bond, lp_interval) +Bridge.HelloTimeSec, config_parse_sec, 0, offsetof(Bridge, hello_time) +Bridge.MaxAgeSec, config_parse_sec, 0, offsetof(Bridge, max_age) +Bridge.ForwardDelaySec, config_parse_sec, 0, offsetof(Bridge, forward_delay) diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index ff1edf2c39..3d4865a780 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -245,6 +245,9 @@ static int netdev_enter_ready(NetDev *netdev) { free(callback); } + if (NETDEV_VTABLE(netdev)->post_create) + NETDEV_VTABLE(netdev)->post_create(netdev, NULL, NULL); + return 0; } diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h index 1f8510c4f7..3b9ab27b67 100644 --- a/src/network/networkd-netdev.h +++ b/src/network/networkd-netdev.h @@ -141,6 +141,9 @@ struct NetDevVTable { /* create netdev, if not done via rtnl */ int (*create)(NetDev *netdev); + /* perform additional configuration after netdev has been createad */ + int (*post_create)(NetDev *netdev, Link *link, sd_netlink_message *message); + /* verify that compulsory configuration options were specified */ int (*config_verify)(NetDev *netdev, const char *filename); }; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 8257ab45da..b6f70e191d 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -61,6 +61,7 @@ Route.Destination, config_parse_destination, Route.Source, config_parse_destination, 0, 0 Route.Metric, config_parse_route_priority, 0, 0 Route.Scope, config_parse_route_scope, 0, 0 +Route.PreferredSource, config_parse_preferred_src, 0, 0 DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier) DHCP.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns) DHCP.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_ntp) diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 1f09d95674..ee1ddd81fe 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -305,6 +305,46 @@ int config_parse_gateway(const char *unit, return 0; } +int config_parse_preferred_src(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *network = userdata; + _cleanup_route_free_ Route *n = NULL; + union in_addr_union buffer; + int r, f; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = route_new_static(network, section_line, &n); + if (r < 0) + return r; + + r = in_addr_from_string_auto(rvalue, &f, &buffer); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Preferred source is invalid, ignoring assignment: %s", rvalue); + return 0; + } + + n->family = f; + n->prefsrc_addr = buffer; + n = NULL; + + return 0; +} + int config_parse_destination(const char *unit, const char *filename, unsigned line, diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index d090b9c91e..11e94d44fb 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -55,6 +55,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free); #define _cleanup_route_free_ _cleanup_(route_freep) int config_parse_gateway(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_preferred_src(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_destination(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_route_priority(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_route_scope(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/systemd/sd-lldp.h b/src/systemd/sd-lldp.h index 0680e526b0..308d42c6e9 100644 --- a/src/systemd/sd-lldp.h +++ b/src/systemd/sd-lldp.h @@ -28,7 +28,14 @@ enum { SD_LLDP_EVENT_UPDATE_INFO = 0, }; +enum { + SD_LLDP_DESTINATION_TYPE_NEAREST_BRIDGE, + SD_LLDP_DESTINATION_TYPE_NEAREST_NON_TPMR_BRIDGE, + SD_LLDP_DESTINATION_TYPE_NEAREST_CUSTOMER_BRIDGE, +}; + typedef struct sd_lldp sd_lldp; +typedef struct tlv_packet sd_lldp_packet; typedef void (*sd_lldp_cb_t)(sd_lldp *lldp, int event, void *userdata); @@ -43,3 +50,25 @@ int sd_lldp_detach_event(sd_lldp *lldp); int sd_lldp_set_callback(sd_lldp *lldp, sd_lldp_cb_t cb, void *userdata); int sd_lldp_save(sd_lldp *lldp, const char *file); + +int sd_lldp_packet_read_chassis_id(sd_lldp_packet *tlv, uint8_t *type, uint8_t **data, uint16_t *length); +int sd_lldp_packet_read_port_id(sd_lldp_packet *tlv, uint8_t *type, uint8_t **data, uint16_t *length); +int sd_lldp_packet_read_ttl(sd_lldp_packet *tlv, uint16_t *ttl); +int sd_lldp_packet_read_system_name(sd_lldp_packet *tlv, char **data, uint16_t *length); +int sd_lldp_packet_read_system_description(sd_lldp_packet *tlv, char **data, uint16_t *length); +int sd_lldp_packet_read_system_capability(sd_lldp_packet *tlv, uint16_t *data); +int sd_lldp_packet_read_port_description(sd_lldp_packet *tlv, char **data, uint16_t *length); + +/* IEEE 802.1 organizationally specific TLVs */ +int sd_lldp_packet_read_port_vlan_id(sd_lldp_packet *tlv, uint16_t *id); +int sd_lldp_packet_read_port_protocol_vlan_id(sd_lldp_packet *tlv, uint8_t *flags, uint16_t *id); +int sd_lldp_packet_read_vlan_name(sd_lldp_packet *tlv, uint16_t *vlan_id, char **name, uint16_t *length); +int sd_lldp_packet_read_management_vid(sd_lldp_packet *tlv, uint16_t *id); +int sd_lldp_packet_read_link_aggregation(sd_lldp_packet *tlv, uint8_t *status, uint32_t *id); + +sd_lldp_packet *sd_lldp_packet_ref(sd_lldp_packet *tlv); +sd_lldp_packet *sd_lldp_packet_unref(sd_lldp_packet *tlv); + +int sd_lldp_packet_get_destination_type(sd_lldp_packet *tlv, int *dest); + +int sd_lldp_get_packets(sd_lldp *lldp, sd_lldp_packet ***tlvs); diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index cb462bf48f..e09b8c8e2d 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -104,6 +104,7 @@ int sd_netlink_message_request_dump(sd_netlink_message *m, int dump); int sd_netlink_message_is_error(sd_netlink_message *m); int sd_netlink_message_get_errno(sd_netlink_message *m); int sd_netlink_message_get_type(sd_netlink_message *m, uint16_t *type); +int sd_netlink_message_set_flags(sd_netlink_message *m, uint16_t flags); int sd_netlink_message_is_broadcast(sd_netlink_message *m); /* rtnl */ diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 83c1793751..10bf3880b0 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1937,7 +1937,8 @@ int udev_rules_apply_to_event(struct udev_rules *rules, break; } } - if (!match && (cur->key.op != OP_NOMATCH)) + if ((!match && (cur->key.op != OP_NOMATCH)) || + (match && (cur->key.op == OP_NOMATCH))) goto nomatch; break; } |