This was previously in openflowext. Now we are adding it to openvswitch.
-Source file copyrights are indicated at the top of each file.
-
-Files not in the datapath/ and vswitchd/ directories or associated
-subdirectories are covered under the OpenFlow license included below:
-
-We are making the OpenFlow specification and associated documentation
-(Software) available for public use and benefit with the expectation
-that others will use, modify and enhance the Software and contribute
-those enhancements back to the community. However, since we would like
-to make the Software available for broadest use, with as few
-restrictions as possible permission is hereby granted, free of charge,
-to any person obtaining a copy of this Software to deal in the Software
-under the copyrights without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-The name and trademarks of copyright holder(s) may NOT be used in
-advertising or publicity pertaining to the Software or any derivatives
-without specific, written prior permission.
-
-Files in the datapath/ and its sub-directories are covered under the GNU
-General Public License Version 2. Included below:
-
-
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-\f
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-\f
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-\f
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-\f
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-\f
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
-
-Files in vswitchd/ and its sub-directories are covered under the GNU
-General Public License Version 3. Included below:
-
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- <program> Copyright (C) <year> <name of author>
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+This file is a summary of the licensing of files in this distribution.
+Some files may be marked specifically with a different license, in
+which case that license applies to the file in question.
+
+Files under the controller, debian, doc, include, lib, m4, secchan,
+tests, third-party, and utilities directories are licensed under the
+following "OpenFlow license":
+
+ We are making the OpenFlow specification and associated documentation
+ (Software) available for public use and benefit with the expectation
+ that others will use, modify and enhance the Software and contribute
+ those enhancements back to the community. However, since we would like
+ to make the Software available for broadest use, with as few
+ restrictions as possible permission is hereby granted, free of charge,
+ to any person obtaining a copy of this Software to deal in the Software
+ under the copyrights without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ The name and trademarks of copyright holder(s) may NOT be used in
+ advertising or publicity pertaining to the Software or any derivatives
+ without specific, written prior permission.
+
+Files under the datapath directory are licensed under the GNU General
+Public License, version 2.
+
+Files under the vswitchd directory are licensed under the GNU General
+Public License, version 3 or later.
+
+Files under the xenserver directory are licensed on a file-by-file
+basis. Some files are under an uncertain license that may not be
+DFSG-compliant or GPL-compatible. Refer to each file for details.
include third-party/automake.mk
include debian/automake.mk
include vswitchd/automake.mk
+include xenserver/automake.mk
include ext.mk
EXTRA_DIST += vswitchd/vswitchd.conf.5.in \
vswitchd/vswitchd.8.in \
- vswitchd/brcompatd.8.in \
- vswitchd/etc
+ vswitchd/brcompatd.8.in
+++ /dev/null
-The files in this subdirectory are intended to be installed into the
-/etc directory of a XenServer. They are added to the XenServer
-distribution tarball by the automatic build system.
+++ /dev/null
-#!/bin/bash
-#
-# vswitch
-#
-# chkconfig: 2345 09 91
-# description: Manage vswitch kernel modules and user-space daemon
-#
-
-. /etc/init.d/functions
-
-test -e /etc/sysconfig/vswitch && . /etc/sysconfig/vswitch
-
-# General config variables in /etc/sysconfig/vswitch
-VSWITCH_BASE="${VSWITCH_BASE:-/root/vswitch}"
-ENABLE_BRCOMPAT="${ENABLE_BRCOMPAT:-y}"
-ENABLE_FAKE_PROC_NET="${ENABLE_FAKE_PROC_NET:-y}"
-FORCE_COREFILES="${FORCE_COREFILES:-n}"
-COREFILE_PATTERN="${COREFILE_PATTERN:-/var/log/%e-%t}"
-
-# Config variables specific to vswitchd
-VSWITCHD_CONF="${VSWITCHD_CONF:-/etc/vswitchd.conf}"
-VSWITCHD_PIDFILE="${VSWITCHD_PIDFILE:-/var/run/vswitchd.pid}"
-VSWITCHD_PRIORITY="${VSWITCHD_PRIORITY:--5}"
-VSWITCHD_LOGFILE="${VSWITCHD_LOGFILE:-/var/log/vswitchd.log}"
-VSWITCHD_FILE_LOGLEVEL="${VSWITCHD_FILE_LOGLEVEL:-}"
-VSWITCHD_SYSLOG_LOGLEVEL="${VSWITCHD_SYSLOG_LOGLEVEL:-WARN}"
-VSWITCHD_MEMLEAK_LOGFILE="${VSWITCHD_MEMLEAK_LOGFILE:-}"
-VSWITCHD_STRACE_LOG="${VSWITCHD_STRACE_LOG:-}"
-VSWITCHD_STRACE_OPT="${VSWITCHD_STRACE_OPT:-}"
-VSWITCHD_VALGRIND_LOG="${VSWITCHD_VALGRIND_LOG:-}"
-VSWITCHD_VALGRIND_OPT="${VSWITCHD_VALGRIND_OPT:-}"
-
-# Config variables specific brcompatd
-BRCOMPATD_PIDFILE="${BRCOMPATD_PIDFILE:-/var/run/brcompatd.pid}"
-BRCOMPATD_PRIORITY="${BRCOMPATD_PRIORITY:--5}"
-BRCOMPATD_LOGFILE="${BRCOMPATD_LOGFILE:-/var/log/brcompatd.log}"
-BRCOMPATD_FILE_LOGLEVEL="${BRCOMPATD_FILE_LOGLEVEL:-}"
-BRCOMPATD_SYSLOG_LOGLEVEL="${BRCOMPATD_SYSLOG_LOGLEVEL:-WARN}"
-BRCOMPATD_MEMLEAK_LOGFILE="${BRCOMPATD_MEMLEAK_LOGFILE:-}"
-BRCOMPATD_STRACE_LOG="${BRCOMPATD_STRACE_LOG:-}"
-BRCOMPATD_STRACE_OPT="${BRCOMPATD_STRACE_OPT:-}"
-BRCOMPATD_VALGRIND_LOG="${BRCOMPATD_VALGRIND_LOG:-}"
-BRCOMPATD_VALGRIND_OPT="${BRCOMPATD_VALGRIND_OPT:-}"
-
-
-
-
-# Full paths to executables & modules
-vswitchd="$VSWITCH_BASE/sbin/vswitchd"
-brcompatd="$VSWITCH_BASE/sbin/brcompatd"
-dpctl="$VSWITCH_BASE/bin/dpctl"
-vlogconf="$VSWITCH_BASE/bin/vlogconf"
-
-
-if [ "$ENABLE_FAKE_PROC_NET" == "y" ]; then
- if [ "$ENABLE_BRCOMPAT" != "y" ]; then
- warning "FAKE_PROC_NET required BRCOMPAT which was disabled. Force enabling."
- ENABLE_BRCOMPAT="y"
- fi
-fi
-
-function dp_list {
- "$dpctl" dp-show | grep '^dp[0-9]\+:' | cut -d':' -f 1
-}
-
-function dp_intf {
- local dp=$1
- # Currently port0 is hardcoded to be the local port.
- "$dpctl" dp-show $dp | grep 'port 0:' | cut -d' ' -f 3
-}
-
-function ifdown_dp_intf {
- for dp in $(dp_list); do
- local intf=$(dp_intf $dp)
- if [ -e "/etc/sysconfig/network-scripts/ifcfg-$intf" ]; then
- action "Bringing down datapath interface: $intf" ifdown "$intf"
- fi
- done
-}
-
-function xen_mgmt_intf {
- ( test -e /etc/xensource-inventory \
- && source /etc/xensource-inventory \
- && echo "$MANAGEMENT_INTERFACE" )
-}
-
-function xen_mgmt_pifdev {
- ( test -e "/etc/sysconfig/network-scripts/ifcfg-$1" \
- && source "/etc/sysconfig/network-scripts/ifcfg-$1" \
- && echo "$PIFDEV" )
-}
-
-function xen_pifdev_hwaddr {
- ( test -e "/etc/sysconfig/network-scripts/ifcfg-$1" \
- && source "/etc/sysconfig/network-scripts/ifcfg-$1" \
- && echo "$HWADDR" )
-}
-
-function allow_xen_mgmt_traffic {
- local mgmt_intf=$(xen_mgmt_intf)
- test -n "$mgmt_intf" || return
- # TBD: This needs to be extended to deal with VLANs, etc.
- local mgmt_pifdev=$(xen_mgmt_pifdev "$mgmt_intf")
- test -n "$mgmt_pifdev" || return
- local mgmt_hwaddr=$(xen_pifdev_hwaddr "$mgmt_pifdev")
- test -n "$mgmt_hwaddr" || return
- action "Inserting dl_addr $mgmt_hwaddr flows for mgmt intf" true
- "$dpctl" add-flow "$mgmt_intf" dl_src="$mgmt_hwaddr",idle_timeout=0,priority=0,action=normal
- "$dpctl" add-flow "$mgmt_intf" dl_dst="$mgmt_hwaddr",idle_timeout=0,priority=0,action=normal
-}
-
-function ifup_dp_intf {
- for dp in $(dp_list); do
- local intf=$(dp_intf $dp)
- if [ -e "/etc/sysconfig/network-scripts/ifcfg-$intf" ]; then
- action "Bringing up datapath interface: $intf" ifup "$intf"
- fi
- done
-}
-
-function turn_on_corefiles {
- # This has global effect so should not normally be used...
- ulimit -c unlimited
- echo "$COREFILE_PATTERN" > /proc/sys/kernel/core_pattern
-}
-
-function remove_all_dp {
- for dp in $(dp_list); do
- action "Removing datapath: $dp" "$dpctl" deldp "$dp"
- done
-}
-
-function insert_modules_if_required {
- if ! lsmod | grep -q "openvswitch_mod"; then
- action "Inserting openvswitch module" insmod $VSWITCH_BASE/kernel_modules/openvswitch_mod.ko
- fi
- if [ -n "$BRCOMPATD_PIDFILE" ] && ! lsmod | grep -q "brcompat_mod"; then
- action "Inserting brcompat module" insmod $VSWITCH_BASE/kernel_modules/brcompat_mod.ko
- fi
-}
-
-function remove_modules {
- if lsmod | grep -q "brcompat_mod"; then
- action "Removing brcompat module" rmmod brcompat_mod.ko
- fi
- if lsmod | grep -q "openvswitch_mod"; then
- action "Removing openvswitch module" rmmod openvswitch_mod.ko
- fi
-}
-
-function reload_vswitchd {
- if [ -f "$VSWITCHD_PIDFILE" ]; then
- "$vlogconf" \
- --target=vswitchd.$(cat "$VSWITCHD_PIDFILE").ctl \
- --execute=vswitchd/reload
- fi
-}
-
-function start_vswitchd {
- local syslog_opt="-vANY:SYSLOG:${VSWITCHD_SYSLOG_LOGLEVEL}"
- local logfile_file_opt=""
- local logfile_level_opt=""
- if [ -n "$VSWITCHD_FILE_LOGLEVEL" ]; then
- logfile_level_opt="-vANY:FILE:${VSWITCHD_FILE_LOGLEVEL}"
- logfile_file_opt="--log-file=$VSWITCHD_LOGFILE"
- fi
- local leak_opt=""
- if [ -n "$VSWITCHD_MEMLEAK_LOGFILE" ]; then
- leak_opt="--check-leaks=$VSWITCHD_MEMLEAK_LOGFILE"
- if [ -e "$VSWITCHD_MEMLEAK_LOGFILE" ]; then
- mv "$VSWITCHD_MEMLEAK_LOGFILE" "$VSWITCHD_MEMLEAK_LOGFILE.prev"
- fi
- fi
- local strace_opt=""
- local daemonize="y"
- if [ -n "$VSWITCHD_STRACE_LOG" ] && [ -n "$VSWITCHD_VALGRIND_LOG" ]; then
- printf "Can not start with both VALGRIND and STRACE\n"
- exit 1
- fi
- if [ -n "$VSWITCHD_STRACE_LOG" ]; then
- strace_opt="strace -o $VSWITCHD_STRACE_LOG $VSWITCHD_STRACE_OPT"
- daemonize="n"
- fi
- if [ -n "$VSWITCHD_VALGRIND_LOG" ]; then
- valgrind_opt="valgrind --log-file=$VSWITCHD_VALGRIND_LOG $VSWITCHD_VALGRIND_OPT"
- daemonize="n"
- fi
- local fake_proc_net_opt=""
- if [ "$ENABLE_FAKE_PROC_NET" == "y" ]; then
- fake_proc_net_opt="--fake-proc-net"
- fi
- if [ "$daemonize" != "y" ]; then
- # Start in background and force a "success" message
- action "Starting vswitchd ($strace_opt$valgrind_opt)" true
- (nice -n "$VSWITCHD_PRIORITY" $strace_opt $valgrind_opt "$vswitchd" -P"$VSWITCHD_PIDFILE" -D $fake_proc_net_opt -vANY:CONSOLE:EMER $syslog_opt $logfile_level_opt $logfile_file_opt $leak_opt "$VSWITCHD_CONF") &
- else
- action "Starting vswitchd" nice -n "$VSWITCHD_PRIORITY" "$vswitchd" -P"$VSWITCHD_PIDFILE" -D $fake_proc_net_opt -vANY:CONSOLE:EMER $syslog_opt $logfile_level_opt $logfile_file_opt $leak_opt "$VSWITCHD_CONF"
- fi
-}
-
-function start_brcompatd {
- local syslog_opt="-vANY:SYSLOG:${BRCOMPATD_SYSLOG_LOGLEVEL}"
- local logfile_file_opt=""
- local logfile_level_opt=""
- if [ -n "$BRCOMPATD_FILE_LOGLEVEL" ]; then
- logfile_level_opt="-vANY:FILE:${BRCOMPATD_FILE_LOGLEVEL}"
- logfile_file_opt="--log-file=$BRCOMPATD_LOGFILE"
- fi
- local leak_opt=""
- if [ -n "$BRCOMPATD_MEMLEAK_LOG" ]; then
- leak_opt="--check-leaks=$BRCOMPATD_MEMLEAK_LOGFILE"
- if [ -e "$BRCOMPATD_MEMLEAK_LOGFILE" ]; then
- mv "$BRCOMPATD_MEMLEAK_LOGFILE" "$BRCOMPATD_MEMLEAK_LOGFILE.prev"
- fi
- fi
- local strace_opt=""
- local daemonize="y"
- if [ -n "$BRCOMPATD_STRACE_LOG" ] && [ -n "$BRCOMPATD_VALGRIND_LOG" ]; then
- printf "Can not start with both VALGRIND and STRACE\n"
- exit 1
- fi
- if [ -n "$BRCOMPATD_STRACE_LOG" ]; then
- strace_opt="strace -o $BRCOMPATD_STRACE_LOG $BRCOMPATD_STRACE_OPT"
- daemonize="n"
- fi
- if [ -n "$VALGRIND_LOG" ]; then
- valgrind_opt="valgrind --log-file=$BRCOMPATD_VALGRIND_LOG $BRCOMPATD_VALGRIND_OPT"
- daemonize="n"
- fi
- if [ "$daemonize" != "y" ]; then
- # Start in background and force a "success" message
- action "Starting brcompatd ($strace_opt$valgrind_opt)" true
- (nice -n "$VSWITCHD_PRIORITY" $strace_opt $valgrind_opt "$brcompatd" -P$BRCOMPATD_PIDFILE --vswitchd-pidfile=$VSWITCHD_PIDFILE -vANY:CONSOLE:EMER $syslog_opt $logfile_level_opt $logfile_file_opt $leak_opt "$VSWITCHD_CONF") &
- else
- action "Starting brcompatd" nice -n "$BRCOMPATD_PRIORITY" $strace_opt $valgrind_opt "$brcompatd" -P$BRCOMPATD_PIDFILE --vswitchd-pidfile=$VSWITCHD_PIDFILE -D -vANY:CONSOLE:EMER $syslog_opt $logfile_level_opt $logfile_file_opt $leak_opt "$VSWITCHD_CONF"
- fi
-}
-
-function stop_vswitchd {
- if [ -f "$VSWITCHD_PIDFILE" ]; then
- local pid=$(cat "$VSWITCHD_PIDFILE")
- action "Killing vswitchd ($pid)" kill -TERM $pid
- rm -f "$VSWITCHD_PIDFILE"
- fi
-}
-
-function stop_brcompatd {
- if [ -f "$BRCOMPATD_PIDFILE" ]; then
- local pid=$(cat "$BRCOMPATD_PIDFILE")
- action "Killing brcompatd ($pid)" kill -TERM $pid
- rm -f "$BRCOMPATD_PIDFILE"
- fi
-}
-
-function restart_approval {
- cat <<EOF
-
-WARNING!!!
-
-Restarting vswitch on a live server is not guaranteed to work. It is
-provided as a convenience for those situations in which it does work.
-If you just want to reload the configuration file, use "reload"
-instead of restart.
-
-EOF
- read -s -r -n 1 -p "Countinue with restart (y/N): " response
- printf "\n"
- case "$response" in
- y|Y)
- return 0
- ;;
- *)
- return 1
- ;;
- esac
-}
-
-function start {
- insert_modules_if_required
- start_vswitchd
- start_brcompatd
- reload_vswitchd # ensures vswitchd has fully read config file.
- #allow_xen_mgmt_traffic # Seems to work okay without...
-}
-
-function stop_unload {
- stop_brcompatd
- ifdown_dp_intf
- remove_all_dp
- stop_vswitchd
- remove_modules
-}
-
-function stop {
- stop_brcompatd
- stop_vswitchd
-}
-
-function restart_unload {
- if restart_approval; then
- stop_unload
- insert_modules_if_required
- start_vswitchd
- reload_vswitchd
- ifup_dp_intf
- start_brcompatd
- fi
-}
-
-function restart {
- if restart_approval; then
- stop
- start
- fi
-}
-
-case "$1" in
- start)
- if [ "$FORCE_COREFILES" == "y" ]; then
- turn_on_corefiles
- fi
- start
- ;;
- stop)
- stop
- ;;
- restart)
- restart
- ;;
- reload)
- reload_vswitchd
- ;;
- strace-vswitchd)
- shift
- strace -p $(cat "$VSWITCHD_PIDFILE") "$@"
- ;;
- strace-brcompatd)
- shift
- strace -p $(cat "$BRCOMPATD_PIDFILE") "$@"
- ;;
- unload)
- stop_unload
- ;;
- update-modules)
- restart_unload
- ;;
- status)
- status -p vswitchd.pid vswitchd
- status -p brcompatd.pid brcompatd
- ;;
- version)
- "$VSWITCH_BASE"/sbin/vswitchd -V
- "$VSWITCH_BASE"/sbin/brcompatd -V
- ;;
- help)
- printf "vswitch [start|stop|restart|reload|unload|status|version]\n"
- ;;
- *)
- printf "Unknown command: $1\n"
- exit 1
- ;;
-esac
+++ /dev/null
-/var/log/vswitchd.log {
- sharedscripts
- postrotate
- # Send sighup to vswitch which will cause it to reopen its log files.
- /sbin/service vswitch reload
- endscript
-}
+++ /dev/null
-PATH=/root/vswitch/bin:$PATH
-export PATH
-MANPATH=/root/vswitch/share/man:$MANPATH
-export MANPATH
-
-alias vswitch='service vswitch'
-
-function watchconf {
- watch cat /etc/vswitchd.conf
-}
-
-function watchdp {
- watch dpctl dp-show "$@"
-}
-
-function watchdpflows {
- local grep=""
- local dp=$1
- shift
- if [ $# -gt 0 ]; then
- grep="| grep $@"
- fi
- watch "dpctl dp-dump-flows $dp $grep"
-}
-
-function watchflows {
- local grep=""
- local dp=$1
- shift
- bridge=$(dpctl dp-show $dp | grep 'port 0:' | cut -d' ' -f 3)
- if [ $# -gt 0 ]; then
- grep="| grep $@"
- fi
- watch "dpctl dump-flows unix:/var/run/$bridge.mgmt $grep"
-}
-
-function monitorlogs {
- local grep=""
- if [ $# -gt 0 ]; then
- grep="| grep --line-buffered '^==> .* <==$"
- for i in "$@"; do
- grep="$grep\|$i"
- done
- grep="$grep'"
- fi
- cmd="tail -F /var/log/messages /var/log/vswitchd.log /var/log/xensource.log $grep | tee /var/log/monitorlogs.out"
- printf "cmd: $cmd\n"
- eval "$cmd"
-}
+++ /dev/null
-### Configuration options for vswitch
-
-# VSWITCH_BASE: Root directory where vswitch binaries are installed
-# VSWITCH_BASE=/root/vswitch/openvswitch/build
-
-# ENABLE_BRCOMPAT: If 'y' than emulate linux bridging interfaces
-# using the brcompat kernel module and brcompatd daemon
-# ENABLE_BRCOMPAT=y
-
-# ENABLE_FAKE_PROC_NET: If 'y' then emulate linux bonding and vlan
-# files in /proc as if the bonding and vlan demultiplexing done in
-# vswitchd were being implemented using existing Linux mechanisms.
-# This is useful in some cases when replacing existing solutions.
-# ENABLE_FAKE_PROC_NET=y
-
-# FORCE_COREFILES: If 'y' then core files will be enabled.
-# FORCE_COREFILES=n
-
-# COREFILE_PATTERN: Pattern used to determine path and filename for
-# core files when FORCE_COREFILES is 'y'. This is Linux specific.
-# See the manpage for "core".
-# COREFILE_PATTERN="/var/log/%e-%t"
-
-# VSWITCHD_CONF: File in which vswitchd stores its configuration.
-# VSWITCHD_CONF=/etc/vswitchd.conf
-
-# VSWITCHD_PIDFILE: File in which to store the pid of the running
-# vswitchd.
-# VSWITCHD_PIDFILE=/var/run/vswitchd.pid
-
-# VSWITCHD_PRIORITY: "nice" priority at which to run vswitchd and related
-# processes.
-# VSWITCHD_PRIORITY=-5
-
-# VSWITCHD_LOGFILE: File to send the FILE_LOGLEVEL log messages to.
-# VSWITCHD_LOGFILE=/var/log/vswitchd.log
-
-# VSWITCHD_FILE_LOGLEVEL: Log level at which to log into the
-# VSWITCHD_LOG file. If this is null or not set the logfile will
-# not be created and nothing will be sent to it. This is the
-# default. The available options are: EMER, WARN, INFO and DBG.
-# VSWITCHD_FILE_LOGLEVEL=""
-
-# VSWITCHD_SYSLOG_LOGLEVEL: Log level at which to log into syslog. If
-# this is null or not set the default is to log to syslog
-# emergency and warning level messages only.
-# VSWITCHD_SYSLOG_LOGLEVEL="WARN"
-
-# BRCOMPATD_PIDFILE: File in which to store the pid of the running
-# brcompatd (the Linux bridge compatibility daemon for vswitchd).
-# If this is the empty string, brcompatd will not be started and
-# the brcompat_mod kernel module will not be inserted. Note that
-# the default is to use brcompat!
-# BRCOMPATD_PIDFILE=/var/run/brcompatd.pid
-
-# BRCOMPATD_PRIORITY: "nice" priority at which to run vswitchd and related
-# processes.
-# BRCOMPATD_PRIORITY=-5
-
-# BRCOMPATD_LOGFILE: File to send the FILE_LOGLEVEL log messages to.
-# BRCOMPATD_LOGFILE=/var/log/brcompatd.log
-
-# BRCOMPATD_FILE_LOGLEVEL: Log level at which to log into the
-# BRCOMPATD_LOG file. If this is null or not set the logfile will
-# not be created and nothing will be sent to it. This is the
-# default. The available options are: EMER, WARN, INFO and DBG.
-# BRCOMPATD_FILE_LOGLEVEL=""
-
-# BRCOMPATD_SYSLOG_LOGLEVEL: Log level at which to log into syslog. If
-# this is null or not set the default is to log to syslog
-# emergency and warning level messages only.
-# BRCOMPATD_SYSLOG_LOGLEVEL="WARN"
--- /dev/null
+This directory contains files for seamless integration of vswitch on
+Citrix XenServer hosts managed by the Citrix management tools.
+
+Some of these files are modifications of Citrix's proprietary code.
+Citrix has given permission to distribute these modified files.
+Citrix has not specified a particular license for them. There is no
+guarantee that, should Citrix specify a license, that it would be
+DFSG-compliant or GPL-compatible.
+
+Most of the files in this directory is installed on a XenServer system
+under the same name, if underscores are replaced by slashes. The
+files are:
+
+ etc_init.d_vswitch
+
+ Initializes the vswitch at boot and shuts it down at shutdown.
+
+ etc_init.d_vswitch-xapi-update
+
+ Init script to ensure vswitch-cfg-update is called for the
+ current host at boot.
+
+ etc_logrotate.d_vswitch
+
+ Ensures that /var/log/vswitchd.log is rotated periodically and
+ that vswitch reopens its log file at that point.
+
+ etc_profile.d_vswitch.sh
+
+ vswitch-related shell functions for the administrator's
+ convenience.
+
+ etc_sysconfig_vswitch.example
+
+ Example configuration options for vswitch.
+
+ etc_xapi.d_plugins_vswitch-cfg-update
+
+ xapi plugin script to update the cache of configuration items
+ in the vswitchd configuration file that are managed in the
+ xapi database when integrated with Citrix management tools.
+
+ etc_xensource_scripts_vif
+
+ vswitch-aware replacement for Citrix script of the same name.
+
+ opt_xensource_libexec_interface-reconfigure
+
+ vswitch-aware replacement for Citrix script of the same name.
+
+ usr_lib_xsconsole_plugins-base_XSFeatureNiciraVSwitch.py
+
+ xsconsole plugin to configure the pool-wide configuration keys
+ used to control vswitch when integrated with Citrix management
+ tools.
+
+ vswitch-xen.spec
+
+ spec file for building RPMs to install on a XenServer host.
+
+To install, build the vswitch RPM with a command like this:
+
+ rpmbuild -D "vswitch_version $full_version" \
+ -D "xen_version $XENKERNEL" \
+ -D "build_number --with-build-number=$buildnr" \
+ -bb vswitch-xen.spec
+
+Then, "rpm -U" the resulting vswitch package on the XenServer hosts in
+question and reboot them. (The vswitch-dbg package that is also
+produced need not be installed, but it is harmless to do so.)
+
+----------------------------------------------------------------------
+Copyright (C) 2009 Nicira Networks, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without warranty of any kind.
--- /dev/null
+# Copyright (C) 2009 Nicira Networks, Inc.
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved. This file is offered as-is,
+# without warranty of any kind.
+
+EXTRA_DIST += \
+ xenserver/README \
+ xenserver/etc_init.d_vswitch \
+ xenserver/etc_init.d_vswitch-xapi-update \
+ xenserver/etc_logrotate.d_vswitch \
+ xenserver/etc_profile.d_vswitch.sh \
+ xenserver/etc_sysconfig_vswitch.example \
+ xenserver/etc_xapi.d_plugins_vswitch-cfg-update \
+ xenserver/etc_xensource_scripts_vif \
+ xenserver/opt_xensource_libexec_interface-reconfigure \
+ xenserver/usr_lib_xsconsole_plugins-base_XSFeatureNiciraVSwitch.py \
+ xenserver/vswitch-xen.spec
--- /dev/null
+#!/bin/bash
+#
+# vswitch
+#
+# chkconfig: 2345 09 91
+# description: Manage vswitch kernel modules and user-space daemon
+
+# Copyright (C) 2009 Nicira Networks, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. /etc/init.d/functions
+
+test -e /etc/sysconfig/vswitch && . /etc/sysconfig/vswitch
+
+# General config variables in /etc/sysconfig/vswitch
+VSWITCH_BASE="${VSWITCH_BASE:-/root/vswitch}"
+ENABLE_BRCOMPAT="${ENABLE_BRCOMPAT:-y}"
+ENABLE_FAKE_PROC_NET="${ENABLE_FAKE_PROC_NET:-y}"
+FORCE_COREFILES="${FORCE_COREFILES:-n}"
+COREFILE_PATTERN="${COREFILE_PATTERN:-/var/log/%e-%t}"
+
+# Config variables specific to vswitchd
+VSWITCHD_CONF="${VSWITCHD_CONF:-/etc/vswitchd.conf}"
+VSWITCHD_PIDFILE="${VSWITCHD_PIDFILE:-/var/run/vswitchd.pid}"
+VSWITCHD_PRIORITY="${VSWITCHD_PRIORITY:--5}"
+VSWITCHD_LOGFILE="${VSWITCHD_LOGFILE:-/var/log/vswitchd.log}"
+VSWITCHD_FILE_LOGLEVEL="${VSWITCHD_FILE_LOGLEVEL:-}"
+VSWITCHD_SYSLOG_LOGLEVEL="${VSWITCHD_SYSLOG_LOGLEVEL:-WARN}"
+VSWITCHD_MEMLEAK_LOGFILE="${VSWITCHD_MEMLEAK_LOGFILE:-}"
+VSWITCHD_STRACE_LOG="${VSWITCHD_STRACE_LOG:-}"
+VSWITCHD_STRACE_OPT="${VSWITCHD_STRACE_OPT:-}"
+VSWITCHD_VALGRIND_LOG="${VSWITCHD_VALGRIND_LOG:-}"
+VSWITCHD_VALGRIND_OPT="${VSWITCHD_VALGRIND_OPT:-}"
+
+# Config variables specific brcompatd
+BRCOMPATD_PIDFILE="${BRCOMPATD_PIDFILE:-/var/run/brcompatd.pid}"
+BRCOMPATD_PRIORITY="${BRCOMPATD_PRIORITY:--5}"
+BRCOMPATD_LOGFILE="${BRCOMPATD_LOGFILE:-/var/log/brcompatd.log}"
+BRCOMPATD_FILE_LOGLEVEL="${BRCOMPATD_FILE_LOGLEVEL:-}"
+BRCOMPATD_SYSLOG_LOGLEVEL="${BRCOMPATD_SYSLOG_LOGLEVEL:-WARN}"
+BRCOMPATD_MEMLEAK_LOGFILE="${BRCOMPATD_MEMLEAK_LOGFILE:-}"
+BRCOMPATD_STRACE_LOG="${BRCOMPATD_STRACE_LOG:-}"
+BRCOMPATD_STRACE_OPT="${BRCOMPATD_STRACE_OPT:-}"
+BRCOMPATD_VALGRIND_LOG="${BRCOMPATD_VALGRIND_LOG:-}"
+BRCOMPATD_VALGRIND_OPT="${BRCOMPATD_VALGRIND_OPT:-}"
+
+
+
+
+# Full paths to executables & modules
+vswitchd="$VSWITCH_BASE/sbin/vswitchd"
+brcompatd="$VSWITCH_BASE/sbin/brcompatd"
+dpctl="$VSWITCH_BASE/bin/dpctl"
+vlogconf="$VSWITCH_BASE/bin/vlogconf"
+
+
+if [ "$ENABLE_FAKE_PROC_NET" == "y" ]; then
+ if [ "$ENABLE_BRCOMPAT" != "y" ]; then
+ warning "FAKE_PROC_NET required BRCOMPAT which was disabled. Force enabling."
+ ENABLE_BRCOMPAT="y"
+ fi
+fi
+
+function dp_list {
+ "$dpctl" dp-show | grep '^dp[0-9]\+:' | cut -d':' -f 1
+}
+
+function dp_intf {
+ local dp=$1
+ # Currently port0 is hardcoded to be the local port.
+ "$dpctl" dp-show $dp | grep 'port 0:' | cut -d' ' -f 3
+}
+
+function ifdown_dp_intf {
+ for dp in $(dp_list); do
+ local intf=$(dp_intf $dp)
+ if [ -e "/etc/sysconfig/network-scripts/ifcfg-$intf" ]; then
+ action "Bringing down datapath interface: $intf" ifdown "$intf"
+ fi
+ done
+}
+
+function xen_mgmt_intf {
+ ( test -e /etc/xensource-inventory \
+ && source /etc/xensource-inventory \
+ && echo "$MANAGEMENT_INTERFACE" )
+}
+
+function xen_mgmt_pifdev {
+ ( test -e "/etc/sysconfig/network-scripts/ifcfg-$1" \
+ && source "/etc/sysconfig/network-scripts/ifcfg-$1" \
+ && echo "$PIFDEV" )
+}
+
+function xen_pifdev_hwaddr {
+ ( test -e "/etc/sysconfig/network-scripts/ifcfg-$1" \
+ && source "/etc/sysconfig/network-scripts/ifcfg-$1" \
+ && echo "$HWADDR" )
+}
+
+function allow_xen_mgmt_traffic {
+ local mgmt_intf=$(xen_mgmt_intf)
+ test -n "$mgmt_intf" || return
+ # TBD: This needs to be extended to deal with VLANs, etc.
+ local mgmt_pifdev=$(xen_mgmt_pifdev "$mgmt_intf")
+ test -n "$mgmt_pifdev" || return
+ local mgmt_hwaddr=$(xen_pifdev_hwaddr "$mgmt_pifdev")
+ test -n "$mgmt_hwaddr" || return
+ action "Inserting dl_addr $mgmt_hwaddr flows for mgmt intf" true
+ "$dpctl" add-flow "$mgmt_intf" dl_src="$mgmt_hwaddr",idle_timeout=0,priority=0,action=normal
+ "$dpctl" add-flow "$mgmt_intf" dl_dst="$mgmt_hwaddr",idle_timeout=0,priority=0,action=normal
+}
+
+function ifup_dp_intf {
+ for dp in $(dp_list); do
+ local intf=$(dp_intf $dp)
+ if [ -e "/etc/sysconfig/network-scripts/ifcfg-$intf" ]; then
+ action "Bringing up datapath interface: $intf" ifup "$intf"
+ fi
+ done
+}
+
+function turn_on_corefiles {
+ # This has global effect so should not normally be used...
+ ulimit -c unlimited
+ echo "$COREFILE_PATTERN" > /proc/sys/kernel/core_pattern
+}
+
+function remove_all_dp {
+ for dp in $(dp_list); do
+ action "Removing datapath: $dp" "$dpctl" deldp "$dp"
+ done
+}
+
+function insert_modules_if_required {
+ if ! lsmod | grep -q "openvswitch_mod"; then
+ action "Inserting openvswitch module" insmod $VSWITCH_BASE/kernel_modules/openvswitch_mod.ko
+ fi
+ if [ -n "$BRCOMPATD_PIDFILE" ] && ! lsmod | grep -q "brcompat_mod"; then
+ action "Inserting brcompat module" insmod $VSWITCH_BASE/kernel_modules/brcompat_mod.ko
+ fi
+}
+
+function remove_modules {
+ if lsmod | grep -q "brcompat_mod"; then
+ action "Removing brcompat module" rmmod brcompat_mod.ko
+ fi
+ if lsmod | grep -q "openvswitch_mod"; then
+ action "Removing openvswitch module" rmmod openvswitch_mod.ko
+ fi
+}
+
+function reload_vswitchd {
+ if [ -f "$VSWITCHD_PIDFILE" ]; then
+ "$vlogconf" \
+ --target=vswitchd.$(cat "$VSWITCHD_PIDFILE").ctl \
+ --execute=vswitchd/reload
+ fi
+}
+
+function start_vswitchd {
+ local syslog_opt="-vANY:SYSLOG:${VSWITCHD_SYSLOG_LOGLEVEL}"
+ local logfile_file_opt=""
+ local logfile_level_opt=""
+ if [ -n "$VSWITCHD_FILE_LOGLEVEL" ]; then
+ logfile_level_opt="-vANY:FILE:${VSWITCHD_FILE_LOGLEVEL}"
+ logfile_file_opt="--log-file=$VSWITCHD_LOGFILE"
+ fi
+ local leak_opt=""
+ if [ -n "$VSWITCHD_MEMLEAK_LOGFILE" ]; then
+ leak_opt="--check-leaks=$VSWITCHD_MEMLEAK_LOGFILE"
+ if [ -e "$VSWITCHD_MEMLEAK_LOGFILE" ]; then
+ mv "$VSWITCHD_MEMLEAK_LOGFILE" "$VSWITCHD_MEMLEAK_LOGFILE.prev"
+ fi
+ fi
+ local strace_opt=""
+ local daemonize="y"
+ if [ -n "$VSWITCHD_STRACE_LOG" ] && [ -n "$VSWITCHD_VALGRIND_LOG" ]; then
+ printf "Can not start with both VALGRIND and STRACE\n"
+ exit 1
+ fi
+ if [ -n "$VSWITCHD_STRACE_LOG" ]; then
+ strace_opt="strace -o $VSWITCHD_STRACE_LOG $VSWITCHD_STRACE_OPT"
+ daemonize="n"
+ fi
+ if [ -n "$VSWITCHD_VALGRIND_LOG" ]; then
+ valgrind_opt="valgrind --log-file=$VSWITCHD_VALGRIND_LOG $VSWITCHD_VALGRIND_OPT"
+ daemonize="n"
+ fi
+ local fake_proc_net_opt=""
+ if [ "$ENABLE_FAKE_PROC_NET" == "y" ]; then
+ fake_proc_net_opt="--fake-proc-net"
+ fi
+ if [ "$daemonize" != "y" ]; then
+ # Start in background and force a "success" message
+ action "Starting vswitchd ($strace_opt$valgrind_opt)" true
+ (nice -n "$VSWITCHD_PRIORITY" $strace_opt $valgrind_opt "$vswitchd" -P"$VSWITCHD_PIDFILE" -D $fake_proc_net_opt -vANY:CONSOLE:EMER $syslog_opt $logfile_level_opt $logfile_file_opt $leak_opt "$VSWITCHD_CONF") &
+ else
+ action "Starting vswitchd" nice -n "$VSWITCHD_PRIORITY" "$vswitchd" -P"$VSWITCHD_PIDFILE" -D $fake_proc_net_opt -vANY:CONSOLE:EMER $syslog_opt $logfile_level_opt $logfile_file_opt $leak_opt "$VSWITCHD_CONF"
+ fi
+}
+
+function start_brcompatd {
+ local syslog_opt="-vANY:SYSLOG:${BRCOMPATD_SYSLOG_LOGLEVEL}"
+ local logfile_file_opt=""
+ local logfile_level_opt=""
+ if [ -n "$BRCOMPATD_FILE_LOGLEVEL" ]; then
+ logfile_level_opt="-vANY:FILE:${BRCOMPATD_FILE_LOGLEVEL}"
+ logfile_file_opt="--log-file=$BRCOMPATD_LOGFILE"
+ fi
+ local leak_opt=""
+ if [ -n "$BRCOMPATD_MEMLEAK_LOG" ]; then
+ leak_opt="--check-leaks=$BRCOMPATD_MEMLEAK_LOGFILE"
+ if [ -e "$BRCOMPATD_MEMLEAK_LOGFILE" ]; then
+ mv "$BRCOMPATD_MEMLEAK_LOGFILE" "$BRCOMPATD_MEMLEAK_LOGFILE.prev"
+ fi
+ fi
+ local strace_opt=""
+ local daemonize="y"
+ if [ -n "$BRCOMPATD_STRACE_LOG" ] && [ -n "$BRCOMPATD_VALGRIND_LOG" ]; then
+ printf "Can not start with both VALGRIND and STRACE\n"
+ exit 1
+ fi
+ if [ -n "$BRCOMPATD_STRACE_LOG" ]; then
+ strace_opt="strace -o $BRCOMPATD_STRACE_LOG $BRCOMPATD_STRACE_OPT"
+ daemonize="n"
+ fi
+ if [ -n "$VALGRIND_LOG" ]; then
+ valgrind_opt="valgrind --log-file=$BRCOMPATD_VALGRIND_LOG $BRCOMPATD_VALGRIND_OPT"
+ daemonize="n"
+ fi
+ if [ "$daemonize" != "y" ]; then
+ # Start in background and force a "success" message
+ action "Starting brcompatd ($strace_opt$valgrind_opt)" true
+ (nice -n "$VSWITCHD_PRIORITY" $strace_opt $valgrind_opt "$brcompatd" -P$BRCOMPATD_PIDFILE --vswitchd-pidfile=$VSWITCHD_PIDFILE -vANY:CONSOLE:EMER $syslog_opt $logfile_level_opt $logfile_file_opt $leak_opt "$VSWITCHD_CONF") &
+ else
+ action "Starting brcompatd" nice -n "$BRCOMPATD_PRIORITY" $strace_opt $valgrind_opt "$brcompatd" -P$BRCOMPATD_PIDFILE --vswitchd-pidfile=$VSWITCHD_PIDFILE -D -vANY:CONSOLE:EMER $syslog_opt $logfile_level_opt $logfile_file_opt $leak_opt "$VSWITCHD_CONF"
+ fi
+}
+
+function stop_vswitchd {
+ if [ -f "$VSWITCHD_PIDFILE" ]; then
+ local pid=$(cat "$VSWITCHD_PIDFILE")
+ action "Killing vswitchd ($pid)" kill -TERM $pid
+ rm -f "$VSWITCHD_PIDFILE"
+ fi
+}
+
+function stop_brcompatd {
+ if [ -f "$BRCOMPATD_PIDFILE" ]; then
+ local pid=$(cat "$BRCOMPATD_PIDFILE")
+ action "Killing brcompatd ($pid)" kill -TERM $pid
+ rm -f "$BRCOMPATD_PIDFILE"
+ fi
+}
+
+function restart_approval {
+ cat <<EOF
+
+WARNING!!!
+
+Restarting vswitch on a live server is not guaranteed to work. It is
+provided as a convenience for those situations in which it does work.
+If you just want to reload the configuration file, use "reload"
+instead of restart.
+
+EOF
+ read -s -r -n 1 -p "Countinue with restart (y/N): " response
+ printf "\n"
+ case "$response" in
+ y|Y)
+ return 0
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+}
+
+function start {
+ insert_modules_if_required
+ start_vswitchd
+ start_brcompatd
+ reload_vswitchd # ensures vswitchd has fully read config file.
+ #allow_xen_mgmt_traffic # Seems to work okay without...
+}
+
+function stop_unload {
+ stop_brcompatd
+ ifdown_dp_intf
+ remove_all_dp
+ stop_vswitchd
+ remove_modules
+}
+
+function stop {
+ stop_brcompatd
+ stop_vswitchd
+}
+
+function restart_unload {
+ if restart_approval; then
+ stop_unload
+ insert_modules_if_required
+ start_vswitchd
+ reload_vswitchd
+ ifup_dp_intf
+ start_brcompatd
+ fi
+}
+
+function restart {
+ if restart_approval; then
+ stop
+ start
+ fi
+}
+
+case "$1" in
+ start)
+ if [ "$FORCE_COREFILES" == "y" ]; then
+ turn_on_corefiles
+ fi
+ start
+ ;;
+ stop)
+ stop
+ ;;
+ restart)
+ restart
+ ;;
+ reload)
+ reload_vswitchd
+ ;;
+ strace-vswitchd)
+ shift
+ strace -p $(cat "$VSWITCHD_PIDFILE") "$@"
+ ;;
+ strace-brcompatd)
+ shift
+ strace -p $(cat "$BRCOMPATD_PIDFILE") "$@"
+ ;;
+ unload)
+ stop_unload
+ ;;
+ update-modules)
+ restart_unload
+ ;;
+ status)
+ status -p vswitchd.pid vswitchd
+ status -p brcompatd.pid brcompatd
+ ;;
+ version)
+ "$VSWITCH_BASE"/sbin/vswitchd -V
+ "$VSWITCH_BASE"/sbin/brcompatd -V
+ ;;
+ help)
+ printf "vswitch [start|stop|restart|reload|unload|status|version]\n"
+ ;;
+ *)
+ printf "Unknown command: $1\n"
+ exit 1
+ ;;
+esac
--- /dev/null
+#!/bin/bash
+#
+# vswitch-xapi-update
+#
+# chkconfig: 2345 95 01
+# description: Update vswitch configuration from XAPI database at boot
+
+# Copyright (C) 2009 Nicira Networks, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. /etc/init.d/functions
+
+test -e /etc/sysconfig/vswitch && . /etc/sysconfig/vswitch
+VSWITCH_BASE="${VSWITCH_BASE:-/root/vswitch}"
+VSWITCHD_CONF="${VSWITCHD_CONF:-/etc/vswitchd.conf}"
+VSWITCHD_PIDFILE="${VSWITCHD_PIDFILE:-/var/run/vswitchd.pid}"
+VSWITCHD_PRIORITY="${VSWITCHD_PRIORITY:--5}"
+VSWITCHD_LOGFILE="${VSWITCHD_LOGFILE:-/var/log/vswitchd.log}"
+VSWITCHD_FILE_LOGLEVEL="${VSWITCHD_FILE_LOGLEVEL:-}"
+VSWITCHD_SYSLOG_LOGLEVEL="${VSWITCHD_SYSLOG_LOGLEVEL:-WARN}"
+VSWITCHD_MEMLEAK_LOGFILE="${VSWITCHD_MEMLEAK_LOGFILE:-}"
+BRCOMPATD_PIDFILE="${BRCOMPATD_PIDFILE:-/var/run/brcompatd.pid}"
+BRCOMPATD_PRIORITY="${BRCOMPATD_PRIORITY:--5}"
+BRCOMPATD_LOGFILE="${BRCOMPATD_LOGFILE:-/var/log/brcompatd.log}"
+BRCOMPATD_FILE_LOGLEVEL="${BRCOMPATD_FILE_LOGLEVEL:-}"
+BRCOMPATD_SYSLOG_LOGLEVEL="${BRCOMPATD_SYSLOG_LOGLEVEL:-WARN}"
+BRCOMPATD_MEMLEAK_LOGFILE="${BRCOMPATD_MEMLEAK_LOGFILE:-}"
+
+function do_host_call {
+ xe host-call-plugin host-uuid="$INSTALLATION_UUID" plugin="vswitch-cfg-update" fn="update" >/dev/null
+}
+
+function start {
+ if [ ! -f /etc/xensource-inventory ]; then
+ printf "vxwitch-xapi-update ERROR: XenSource inventory not present in /etc/xensource-inventory\n"
+ exit 1
+ fi
+ source /etc/xensource-inventory
+ action "Updating configuration" do_host_call
+}
+
+case "$1" in
+ start)
+ start
+ ;;
+ stop)
+ # Nothing to do here.
+ ;;
+ restart)
+ start
+ ;;
+ help)
+ printf "vswitch [start|stop|restart]\n"
+ ;;
+ *)
+ printf "Unknown command: $1\n"
+ exit 1
+ ;;
+esac
--- /dev/null
+# Copyright (C) 2009 Nicira Networks, Inc.
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved. This file is offered as-is,
+# without warranty of any kind.
+
+/var/log/vswitchd.log {
+ sharedscripts
+ postrotate
+ # Send sighup to vswitch which will cause it to reopen its log files.
+ /sbin/service vswitch reload
+ endscript
+}
--- /dev/null
+# Copyright (C) 2009 Nicira Networks, Inc.
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved. This file is offered as-is,
+# without warranty of any kind.
+
+PATH=/root/vswitch/bin:$PATH
+export PATH
+MANPATH=/root/vswitch/share/man:$MANPATH
+export MANPATH
+
+alias vswitch='service vswitch'
+
+function watchconf {
+ watch cat /etc/vswitchd.conf
+}
+
+function watchdp {
+ watch dpctl dp-show "$@"
+}
+
+function watchdpflows {
+ local grep=""
+ local dp=$1
+ shift
+ if [ $# -gt 0 ]; then
+ grep="| grep $@"
+ fi
+ watch "dpctl dp-dump-flows $dp $grep"
+}
+
+function watchflows {
+ local grep=""
+ local dp=$1
+ shift
+ bridge=$(dpctl dp-show $dp | grep 'port 0:' | cut -d' ' -f 3)
+ if [ $# -gt 0 ]; then
+ grep="| grep $@"
+ fi
+ watch "dpctl dump-flows unix:/var/run/$bridge.mgmt $grep"
+}
+
+function monitorlogs {
+ local grep=""
+ if [ $# -gt 0 ]; then
+ grep="| grep --line-buffered '^==> .* <==$"
+ for i in "$@"; do
+ grep="$grep\|$i"
+ done
+ grep="$grep'"
+ fi
+ cmd="tail -F /var/log/messages /var/log/vswitchd.log /var/log/xensource.log $grep | tee /var/log/monitorlogs.out"
+ printf "cmd: $cmd\n"
+ eval "$cmd"
+}
--- /dev/null
+### Configuration options for vswitch
+
+# Copyright (C) 2009 Nicira Networks, Inc.
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved. This file is offered as-is,
+# without warranty of any kind.
+
+# VSWITCH_BASE: Root directory where vswitch binaries are installed
+# VSWITCH_BASE=/root/vswitch/openvswitch/build
+
+# ENABLE_BRCOMPAT: If 'y' than emulate linux bridging interfaces
+# using the brcompat kernel module and brcompatd daemon
+# ENABLE_BRCOMPAT=y
+
+# ENABLE_FAKE_PROC_NET: If 'y' then emulate linux bonding and vlan
+# files in /proc as if the bonding and vlan demultiplexing done in
+# vswitchd were being implemented using existing Linux mechanisms.
+# This is useful in some cases when replacing existing solutions.
+# ENABLE_FAKE_PROC_NET=y
+
+# FORCE_COREFILES: If 'y' then core files will be enabled.
+# FORCE_COREFILES=n
+
+# COREFILE_PATTERN: Pattern used to determine path and filename for
+# core files when FORCE_COREFILES is 'y'. This is Linux specific.
+# See the manpage for "core".
+# COREFILE_PATTERN="/var/log/%e-%t"
+
+# VSWITCHD_CONF: File in which vswitchd stores its configuration.
+# VSWITCHD_CONF=/etc/vswitchd.conf
+
+# VSWITCHD_PIDFILE: File in which to store the pid of the running
+# vswitchd.
+# VSWITCHD_PIDFILE=/var/run/vswitchd.pid
+
+# VSWITCHD_PRIORITY: "nice" priority at which to run vswitchd and related
+# processes.
+# VSWITCHD_PRIORITY=-5
+
+# VSWITCHD_LOGFILE: File to send the FILE_LOGLEVEL log messages to.
+# VSWITCHD_LOGFILE=/var/log/vswitchd.log
+
+# VSWITCHD_FILE_LOGLEVEL: Log level at which to log into the
+# VSWITCHD_LOG file. If this is null or not set the logfile will
+# not be created and nothing will be sent to it. This is the
+# default. The available options are: EMER, WARN, INFO and DBG.
+# VSWITCHD_FILE_LOGLEVEL=""
+
+# VSWITCHD_SYSLOG_LOGLEVEL: Log level at which to log into syslog. If
+# this is null or not set the default is to log to syslog
+# emergency and warning level messages only.
+# VSWITCHD_SYSLOG_LOGLEVEL="WARN"
+
+# BRCOMPATD_PIDFILE: File in which to store the pid of the running
+# brcompatd (the Linux bridge compatibility daemon for vswitchd).
+# If this is the empty string, brcompatd will not be started and
+# the brcompat_mod kernel module will not be inserted. Note that
+# the default is to use brcompat!
+# BRCOMPATD_PIDFILE=/var/run/brcompatd.pid
+
+# BRCOMPATD_PRIORITY: "nice" priority at which to run vswitchd and related
+# processes.
+# BRCOMPATD_PRIORITY=-5
+
+# BRCOMPATD_LOGFILE: File to send the FILE_LOGLEVEL log messages to.
+# BRCOMPATD_LOGFILE=/var/log/brcompatd.log
+
+# BRCOMPATD_FILE_LOGLEVEL: Log level at which to log into the
+# BRCOMPATD_LOG file. If this is null or not set the logfile will
+# not be created and nothing will be sent to it. This is the
+# default. The available options are: EMER, WARN, INFO and DBG.
+# BRCOMPATD_FILE_LOGLEVEL=""
+
+# BRCOMPATD_SYSLOG_LOGLEVEL: Log level at which to log into syslog. If
+# this is null or not set the default is to log to syslog
+# emergency and warning level messages only.
+# BRCOMPATD_SYSLOG_LOGLEVEL="WARN"
--- /dev/null
+#!/usr/bin/env python
+#
+# xapi plugin script to update the cache of configuration items in the
+# vswitchd configuration file that are managed in the xapi database
+# when integrated with Citrix management tools.
+
+# Copyright (C) 2009 Nicira Networks, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# TBD: - error handling needs to be improved. Currently this can leave
+# TBD: the system in a bad state if anything goes wrong.
+
+import logging
+log = logging.getLogger("vswitch-cfg-update")
+logging.basicConfig(filename="/var/log/vswitch-cfg-update.log", level=logging.DEBUG)
+
+import XenAPIPlugin
+import XenAPI
+import subprocess
+
+cfg_mod="/root/vswitch/bin/cfg-mod"
+vswitchd_cfg_filename="/etc/vswitchd.conf"
+
+def update(session, args):
+ pools = session.xenapi.pool.get_all()
+ # We assume there is only ever one pool...
+ if len(pools) == 0:
+ log.error("No pool for host.")
+ raise XenAPIPlugin.Failure("NO_POOL_FOR_HOST", [])
+ if len(pools) > 1:
+ log.error("More than one pool for host.")
+ raise XenAPIPlugin.Failure("MORE_THAN_ONE_POOL_FOR_HOST", [])
+ pool = session.xenapi.pool.get_record(pools[0])
+ try:
+ controller = pool["other_config"]["niciraController"]
+ except KeyError, e:
+ controller = ""
+ currentController = vswitchCurrentController()
+ if controller == "" and currentController != "":
+ log.debug("Removing controller configuration.")
+ removeControllerCfg()
+ return "Successfully removed controller config"
+ elif controller != currentController:
+ if len(controller) == 0:
+ log.debug("Setting controller to: %s" % (controller))
+ else:
+ log.debug("Changing controller from %s to %s" % (currentController, controller))
+ setControllerCfg(controller)
+ return "Successfully set controller to " + controller
+ else:
+ log.debug("No change to controller configuration required.")
+ return "No change to configuration"
+
+def vswitchCurrentController():
+ controller = vswitchCfgQuery("mgmt.controller")
+ if controller == "":
+ return controller
+ if len(controller) < 4 or controller[0:4] != "ssl:":
+ log.warning("Controller does not specify ssl connection type, returning entire string.")
+ return controller
+ else:
+ return controller[4:]
+
+def removeControllerCfg():
+ vswitchCfgMod(["--del-match", "mgmt.controller=*",
+ "--del-match", "ssl.bootstrap-ca-cert=*",
+ "--del-match", "ssl.ca-cert=*",
+ "--del-match", "ssl.private-key=*",
+ "--del-match", "ssl.certificate=*"])
+
+def setControllerCfg(controller):
+ vswitchCfgMod(["--del-match", "mgmt.controller=*",
+ "--del-match", "ssl.bootstrap-ca-cert=*",
+ "--del-match", "ssl.ca-cert=*",
+ "--del-match", "ssl.private-key=*",
+ "--del-match", "ssl.certificate=*",
+ "-a", "mgmt.controller=ssl:" + controller,
+ "-a", "ssl.bootstrap-ca-cert=true",
+ "-a", "ssl.ca-cert=/etc/vswitchd.cacert",
+ "-a", "ssl.private-key=/etc/xensource/xapi-ssl.pem",
+ "-a", "ssl.certificate=/etc/xensource/xapi-ssl.pem"])
+
+def vswitchCfgQuery(key):
+ cmd = [cfg_mod, "--config-file=" + vswitchd_cfg_filename, "-q", key]
+ output = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()
+ if len(output) == 0 or output[0] == None:
+ output = ""
+ else:
+ output = output[0].strip()
+ return output
+
+def vswitchCfgMod(action_args):
+ cmd = [cfg_mod, "--config-file=" + vswitchd_cfg_filename] + action_args
+ exitcode = subprocess.call(cmd)
+ if exitcode != 0:
+ log.error("cfg-mod failed with exit code "
+ + str(exitcode) + " for " + repr(action_args))
+ raise XenAPIPlugin.Failure("VSWITCH_CONFIG_MOD_FAILURE",
+ [ str(exitcode) , str(action_args) ])
+ vswitchReload()
+
+def vswitchReload():
+ exitcode = subprocess.call(["/sbin/service", "vswitch", "reload"])
+ if exitcode != 0:
+ log.error("vswitch reload failed with exit code " + str(exitcode))
+ raise XenAPIPlugin.Failure("VSWITCH_CFG_RELOAD_FAILURE", [ str(exitcode) ])
+
+
+if __name__ == "__main__":
+ XenAPIPlugin.dispatch({"update": update})
--- /dev/null
+#!/bin/sh
+
+# This file is based on /etc/xensource/script/vif from Citrix XenServer 5.0.0.
+# The original file did not contain a copyright notice or license statement.
+#
+# Copyright (C) 2009 Nicira Networks, Inc.
+
+# CA-23900: Warning: when VIFs are added to windows guests with PV drivers the backend vif device is registered,
+# unregistered and then registered again. This causes the udev event to fire twice and this script runs twice.
+# Since the first invocation of the script races with the device unregistration, spurious errors are possible
+# which will be logged but are safe to ignore since the second script invocation should complete the operation.
+# Note that each script invocation is run synchronously from udev and so the scripts don't race with each other.
+
+# Keep other-config/ keys in sync with device.ml:vif_udev_keys
+
+cfg_mod="/root/vswitch/bin/cfg-mod"
+service="/sbin/service"
+
+TYPE=`echo ${XENBUS_PATH} | cut -f 2 -d '/'`
+DOMID=`echo ${XENBUS_PATH} | cut -f 3 -d '/'`
+DEVID=`echo ${XENBUS_PATH} | cut -f 4 -d '/'`
+
+XAPI=/xapi/${DOMID}/hotplug/${TYPE}/${DEVID}
+HOTPLUG=/xapi/${DOMID}/hotplug/${TYPE}/${DEVID}
+PRIVATE=/xapi/${DOMID}/private/${TYPE}/${DEVID}
+BRCTL=/usr/sbin/brctl
+IP=/sbin/ip
+
+
+handle_promiscuous()
+{
+ local arg=$(xenstore-read "${PRIVATE}/other-config/promiscuous")
+ if [ $? -eq 0 -a -n "${arg}" ] ; then
+ case "${arg}" in
+ true|on) echo 1 > /sys/class/net/${vif}/brport/promisc ;;
+ *) echo 0 > /sys/class/net/${vif}/brport/promisc ;;
+ esac
+ fi
+}
+
+handle_ethtool()
+{
+ local opt=$1
+ local arg=$(xenstore-read "${PRIVATE}/other-config/ethtool-${opt}")
+ if [ $? -eq 0 -a -n "${arg}" ] ; then
+ case "${arg}" in
+ true|on) /sbin/ethtool -K "${vif}" "${opt}" on ;;
+ false|off) /sbin/ethtool -K "${vif}" "${opt}" off ;;
+ *) logger -t scripts-vif "Unknown ethtool argument ${opt}=${arg} on ${vif}/${VIFUUID}" ;;
+ esac
+ fi
+}
+
+handle_mtu()
+{
+ local mtu=$(xenstore-read "${PRIVATE}/MTU")
+ if [ $? -eq 0 -a -n "${mtu}" ]; then
+ echo "${mtu}" > /sys/class/net/${vif}/mtu
+ fi
+}
+
+add_to_bridge()
+{
+ local address=$(xenstore-read "${PRIVATE}/bridge-MAC")
+ if [ $? -ne 0 -o -z "${address}" ]; then
+ logger -t scripts-vif "Failed to read ${PRIVATE}/bridge-MAC from xenstore"
+ fi
+ local bridge=$(xenstore-read "${PRIVATE}/bridge")
+ if [ $? -ne 0 -o -z "${bridge}" ]; then
+ logger -t scripts-vif "Failed to read ${PRIVATE}/bridge from xenstore"
+ fi
+ logger -t scripts-vif "Adding ${vif} to ${bridge} with address ${address}"
+
+ vid=
+ if [ -e "/etc/sysconfig/network-scripts/ifcfg-$bridge" ]; then
+ . "/etc/sysconfig/network-scripts/ifcfg-$bridge"
+ if [ -n "$VLAN_SLAVE" -a -n "$VLAN_VID" ]; then
+ bridge=$VLAN_SLAVE
+ vid="--add=vlan.$vif.tag=$VLAN_VID"
+ fi
+ fi
+
+ ${IP} link set "${vif}" down || logger -t scripts-vif "Failed to ip link set ${vif} down"
+ ${IP} link set "${vif}" arp off || logger -t scripts-vif "Failed to ip link set ${vif} arp off"
+ ${IP} link set "${vif}" multicast off || logger -t scripts-vif "Failed to ip link set ${vif} multicast off"
+ ${IP} link set "${vif}" address "${address}" || logger -t scripts-vif "Failed to ip link set ${vif} address ${address}"
+ ${IP} addr flush "${vif}" || logger -t scripts-vif "Failed to ip addr flush ${vif}"
+
+ $cfg_mod -F /etc/vswitchd.conf \
+ --del-match="bridge.*.port=$vif" \
+ --del-match="vlan.$vif.[!0-9]*" \
+ --add="bridge.$bridge.port=$vif" \
+ $vid
+ $service vswitch reload
+
+ ${IP} link set "${vif}" up || logger -t scripts-vif "Failed to ip link set ${vif} up"
+}
+
+echo Called as "$@" "$TYPE" "$DOMID" "$DEVID" | logger -t scripts-vif
+case "$1" in
+online)
+ handle_ethtool rx
+ handle_ethtool tx
+ handle_ethtool sg
+ handle_ethtool tso
+ handle_ethtool ufo
+ handle_ethtool gso
+
+ handle_mtu
+ add_to_bridge
+ handle_promiscuous
+
+ xenstore-write "${HOTPLUG}/vif" "${vif}"
+ xenstore-write "${HOTPLUG}/hotplug" "online"
+
+ # xs-xen.pq.hq:91e986b8e49f netback-wait-for-hotplug
+ xenstore-write "/local/domain/0/backend/vif/${DOMID}/${DEVID}/hotplug-status" "connected"
+
+ ;;
+remove)
+ xenstore-rm "${HOTPLUG}/hotplug"
+ vif=vif${DOMID}.${DEVID}
+ logger -t scripts-vif "${vif} has been removed"
+ $cfg-mod -F /etc/vswitchd.conf --del-match="bridge.*.port=${vif}" \
+ --del-match="vlan.${vif}.[!0-9]*"
+ ;;
+esac
--- /dev/null
+#!/usr/bin/python
+#
+# Copyright (c) Citrix Systems 2008. All rights reserved.
+# Copyright (c) Nicira Networks 2009.
+#
+"""Usage:
+
+ %(command-name)s --session <SESSION-REF> --pif <PIF-REF> [up|down|rewrite]
+ %(command-name)s --force <BRIDGE> [up|down|rewrite <CONFIG>]
+ %(command-name)s --force all down
+
+ where,
+ <CONFIG> = --device=<INTERFACE> --mode=dhcp
+ <CONFIG> = --device=<INTERFACE> --mode=static --ip=<IPADDR> --netmask=<NM> [--gateway=<GW>]
+
+ Options:
+ --session A session reference to use to access the xapi DB
+ --pif A PIF reference.
+ --force-interface An interface name. Mutually exclusive with --session/--pif.
+
+ Either both --session and --pif or just --pif-uuid.
+
+ <ACTION> is either "up" or "down" or "rewrite"
+"""
+
+#
+# Undocumented parameters for test & dev:
+#
+# --output-directory=<DIR> Write configuration to <DIR>. Also disables actually
+# raising/lowering the interfaces
+# --pif-uuid A PIF UUID, use instead of --session/--pif.
+#
+#
+#
+# Notes:
+# 1. Every pif belongs to exactly one network
+# 2. Every network has zero or one pifs
+# 3. A network may have an associated bridge, allowing vifs to be attached
+# 4. A network may be bridgeless (there's no point having a bridge over a storage pif)
+
+# XXX: --force-interface=all down
+
+import XenAPI
+import os, sys, getopt, time, signal
+import syslog
+import traceback
+import time
+import re
+import pickle
+
+output_directory = None
+
+db = None
+management_pif = None
+
+dbcache_file = "/etc/vswitch.dbcache"
+
+class Usage(Exception):
+ def __init__(self, msg):
+ Exception.__init__(self)
+ self.msg = msg
+
+class Error(Exception):
+ def __init__(self, msg):
+ Exception.__init__(self)
+ self.msg = msg
+
+class ConfigurationFile(object):
+ """Write a file, tracking old and new versions.
+
+ Supports writing a new version of a file and applying and
+ reverting those changes.
+ """
+
+ __STATE = {"OPEN":"OPEN",
+ "NOT-APPLIED":"NOT-APPLIED", "APPLIED":"APPLIED",
+ "REVERTED":"REVERTED", "COMMITTED": "COMMITTED"}
+
+ def __init__(self, fname, path):
+
+ self.__state = self.__STATE['OPEN']
+ self.__fname = fname
+ self.__children = []
+
+ if debug_mode():
+ dirname = output_directory
+ else:
+ dirname = path
+
+ self.__path = os.path.join(dirname, fname)
+ self.__oldpath = os.path.join(dirname, "." + fname + ".xapi-old")
+ self.__newpath = os.path.join(dirname, "." + fname + ".xapi-new")
+ self.__unlink = False
+
+ self.__f = open(self.__newpath, "w")
+
+ def attach_child(self, child):
+ self.__children.append(child)
+
+ def path(self):
+ return self.__path
+
+ def readlines(self):
+ try:
+ return open(self.path()).readlines()
+ except:
+ return ""
+
+ def write(self, args):
+ if self.__state != self.__STATE['OPEN']:
+ raise Error("Attempt to write to file in state %s" % self.__state)
+ self.__f.write(args)
+
+ def unlink(self):
+ if self.__state != self.__STATE['OPEN']:
+ raise Error("Attempt to unlink file in state %s" % self.__state)
+ self.__unlink = True
+ self.__f.close()
+ self.__state = self.__STATE['NOT-APPLIED']
+
+ def close(self):
+ if self.__state != self.__STATE['OPEN']:
+ raise Error("Attempt to close file in state %s" % self.__state)
+
+ self.__f.close()
+ self.__state = self.__STATE['NOT-APPLIED']
+
+ def changed(self):
+ if self.__state != self.__STATE['NOT-APPLIED']:
+ raise Error("Attempt to compare file in state %s" % self.__state)
+
+ return True
+
+ def apply(self):
+ if self.__state != self.__STATE['NOT-APPLIED']:
+ raise Error("Attempt to apply configuration from state %s" % self.__state)
+
+ for child in self.__children:
+ child.apply()
+
+ log("Applying changes to %s configuration" % self.__fname)
+
+ # Remove previous backup.
+ if os.access(self.__oldpath, os.F_OK):
+ os.unlink(self.__oldpath)
+
+ # Save current configuration.
+ if os.access(self.__path, os.F_OK):
+ os.link(self.__path, self.__oldpath)
+ os.unlink(self.__path)
+
+ # Apply new configuration.
+ assert(os.path.exists(self.__newpath))
+ if not self.__unlink:
+ os.link(self.__newpath, self.__path)
+ else:
+ pass # implicit unlink of original file
+
+ # Remove temporary file.
+ os.unlink(self.__newpath)
+
+ self.__state = self.__STATE['APPLIED']
+
+ def revert(self):
+ if self.__state != self.__STATE['APPLIED']:
+ raise Error("Attempt to revert configuration from state %s" % self.__state)
+
+ for child in self.__children:
+ child.revert()
+
+ log("Reverting changes to %s configuration" % self.__fname)
+
+ # Remove existing new configuration
+ if os.access(self.__newpath, os.F_OK):
+ os.unlink(self.__newpath)
+
+ # Revert new configuration.
+ if os.access(self.__path, os.F_OK):
+ os.link(self.__path, self.__newpath)
+ os.unlink(self.__path)
+
+ # Revert to old configuration.
+ if os.access(self.__oldpath, os.F_OK):
+ os.link(self.__oldpath, self.__path)
+ os.unlink(self.__oldpath)
+
+ # Leave .*.xapi-new as an aid to debugging.
+
+ self.__state = self.__STATE['REVERTED']
+
+ def commit(self):
+ if self.__state != self.__STATE['APPLIED']:
+ raise Error("Attempt to commit configuration from state %s" % self.__state)
+
+ for child in self.__children:
+ child.commit()
+
+ log("Committing changes to %s configuration" % self.__fname)
+
+ if os.access(self.__oldpath, os.F_OK):
+ os.unlink(self.__oldpath)
+ if os.access(self.__newpath, os.F_OK):
+ os.unlink(self.__newpath)
+
+ self.__state = self.__STATE['COMMITTED']
+
+def debug_mode():
+ return output_directory is not None
+
+def log(s):
+ if debug_mode():
+ print >>sys.stderr, s
+ else:
+ syslog.syslog(s)
+
+def check_allowed(pif):
+ pifrec = db.get_pif_record(pif)
+ try:
+ f = open("/proc/ardence")
+ macline = filter(lambda x: x.startswith("HWaddr:"), f.readlines())
+ f.close()
+ if len(macline) == 1:
+ p = re.compile(".*\s%(MAC)s\s.*" % pifrec, re.IGNORECASE)
+ if p.match(macline[0]):
+ log("Skipping PVS device %(device)s (%(MAC)s)" % pifrec)
+ return False
+ except IOError:
+ pass
+ return True
+
+def interface_exists(i):
+ return os.path.exists("/sys/class/net/" + i)
+
+class DatabaseCache(object):
+ def __init__(self, session_ref=None, cache_file=None):
+ if session_ref and cache_file:
+ raise Error("can't specify session reference and cache file")
+
+ if cache_file == None:
+ session = XenAPI.xapi_local()
+
+ if not session_ref:
+ log("No session ref given on command line, logging in.")
+ session.xenapi.login_with_password("root", "")
+ else:
+ session._session = session_ref
+
+ try:
+ self.__vlans = session.xenapi.VLAN.get_all_records()
+ self.__bonds = session.xenapi.Bond.get_all_records()
+ self.__pifs = session.xenapi.PIF.get_all_records()
+ self.__networks = session.xenapi.network.get_all_records()
+ finally:
+ if not session_ref:
+ session.xenapi.session.logout()
+ else:
+ log("Loading xapi database cache from %s" % cache_file)
+ f = open(cache_file, 'r')
+ members = pickle.load(f)
+ self.extras = pickle.load(f)
+ f.close()
+
+ self.__vlans = members['vlans']
+ self.__bonds = members['bonds']
+ self.__pifs = members['pifs']
+ self.__networks = members['networks']
+
+ def save(self, cache_file, extras):
+ f = open(cache_file, 'w')
+ pickle.dump({'vlans': self.__vlans,
+ 'bonds': self.__bonds,
+ 'pifs': self.__pifs,
+ 'networks': self.__networks}, f)
+ pickle.dump(extras, f)
+ f.close()
+
+ def get_pif_by_uuid(self, uuid):
+ pifs = map(lambda (ref,rec): ref,
+ filter(lambda (ref,rec): uuid == rec['uuid'],
+ self.__pifs.items()))
+ if len(pifs) == 0:
+ raise Error("Unknown PIF \"%s\"" % uuid)
+ elif len(pifs) > 1:
+ raise Error("Non-unique PIF \"%s\"" % uuid)
+
+ return pifs[0]
+
+ def get_pif_by_record(self, record):
+ """record is partial pif record.
+ Get the pif whose record matches.
+ """
+ def match(pifrec):
+ for key in record:
+ if record[key] != pifrec[key]:
+ return False
+ return True
+
+ pifs = map(lambda (ref,rec): ref,
+ filter(lambda (ref,rec): match(rec),
+ self.__pifs.items()))
+ if len(pifs) == 0:
+ raise Error("No matching PIF \"%s\"" % str(record))
+ elif len(pifs) > 1:
+ raise Error("Multiple matching PIFs \"%s\"" % str(record))
+
+ return pifs[0]
+
+ def get_pif_by_bridge(self, host, bridge):
+ networks = map(lambda (ref,rec): ref,
+ filter(lambda (ref,rec): rec['bridge'] == bridge,
+ self.__networks.items()))
+ if len(networks) == 0:
+ raise Error("No matching network \"%s\"")
+
+ answer = None
+ for network in networks:
+ nwrec = self.get_network_record(network)
+ pif_uuids = nwrec['PIFs']
+ if len(pif_uuids) != 1:
+ continue
+ pif = pif_uuids[0]
+ pifrec = self.get_pif_record(pif)
+ if pifrec['host'] != host:
+ continue
+ if answer:
+ raise Error("Multiple PIFs on %s for network %s" % (host, bridge))
+ answer = pif
+ if not answer:
+ raise Error("No PIF on %s for network %s" % (host, bridge))
+ return answer
+
+ def get_pif_record(self, pif):
+ if self.__pifs.has_key(pif):
+ return self.__pifs[pif]
+ raise Error("Unknown PIF \"%s\"" % pif)
+ def get_all_pifs(self):
+ return self.__pifs
+ def pif_exists(self, pif):
+ return self.__pifs.has_key(pif)
+
+ def get_management_pif(self, host):
+ """ Returns the management pif on host
+ """
+ all = self.get_all_pifs()
+ for pif in all:
+ pifrec = self.get_pif_record(pif)
+ if pifrec['management'] and pifrec['host'] == host :
+ return pif
+ return None
+
+ def get_network_record(self, network):
+ if self.__networks.has_key(network):
+ return self.__networks[network]
+ raise Error("Unknown network \"%s\"" % network)
+
+ def get_bond_record(self, bond):
+ if self.__bonds.has_key(bond):
+ return self.__bonds[bond]
+ else:
+ return None
+
+ def get_vlan_record(self, vlan):
+ if self.__vlans.has_key(vlan):
+ return self.__vlans[vlan]
+ else:
+ return None
+
+def bridge_name(pif):
+ """Return the bridge name associated with pif, or None if network is bridgeless"""
+ pifrec = db.get_pif_record(pif)
+ nwrec = db.get_network_record(pifrec['network'])
+
+ if nwrec['bridge']:
+ # TODO: sanity check that nwrec['bridgeless'] != 'true'
+ return nwrec['bridge']
+ else:
+ # TODO: sanity check that nwrec['bridgeless'] == 'true'
+ return None
+
+def interface_name(pif):
+ """Construct an interface name from the given PIF record."""
+
+ pifrec = db.get_pif_record(pif)
+
+ if pifrec['VLAN'] == '-1':
+ return pifrec['device']
+ else:
+ return "%(device)s.%(VLAN)s" % pifrec
+
+def datapath_name(pif):
+ """Return the OpenFlow datapath name associated with pif.
+For a non-VLAN PIF, the datapath name is the bridge name.
+For a VLAN PIF, the datapath name is the bridge name for the PIF's VLAN slave.
+(xapi will create a datapath named with the bridge name even though we won't
+use it.)
+"""
+
+ pifrec = db.get_pif_record(pif)
+
+ if pifrec['VLAN'] == '-1':
+ return bridge_name(pif)
+ else:
+ return bridge_name(get_vlan_slave_of_pif(pif))
+
+def ipdev_name(pif):
+ """Return the the name of the network device that carries the
+IP configuration (if any) associated with pif.
+For a non-VLAN PIF, the ipdev name is the bridge name.
+For a VLAN PIF, the ipdev name is the interface name.
+"""
+
+ pifrec = db.get_pif_record(pif)
+
+ if pifrec['VLAN'] == '-1':
+ return bridge_name(pif)
+ else:
+ return interface_name(pif)
+
+def physdev_names(pif):
+ """Return the name(s) of the physical network device(s) associated with pif.
+For a VLAN PIF, the physical devices are the VLAN slave's physical devices.
+For a bond master PIF, the physical devices are the bond slaves.
+For a non-VLAN, non-bond master PIF, the physical device is the PIF itself.
+"""
+
+ pifrec = db.get_pif_record(pif)
+
+ if pifrec['VLAN'] != '-1':
+ return physdev_names(get_vlan_slave_of_pif(pif))
+ elif len(pifrec['bond_master_of']) != 0:
+ physdevs = []
+ for slave in get_bond_slaves_of_pif(pif):
+ physdevs += physdev_names(slave)
+ return physdevs
+ else:
+ return [pifrec['device']]
+
+def log_pif_action(action, pif):
+ pifrec = db.get_pif_record(pif)
+ pifrec['action'] = action
+ pifrec['interface-name'] = interface_name(pif)
+ if action == "rewrite":
+ pifrec['message'] = "Rewrite PIF %(uuid)s configuration" % pifrec
+ else:
+ pifrec['message'] = "Bring %(action)s PIF %(uuid)s" % pifrec
+ log("%(message)s: %(interface-name)s configured as %(ip_configuration_mode)s" % pifrec)
+
+def get_bond_masters_of_pif(pif):
+ """Returns a list of PIFs which are bond masters of this PIF"""
+
+ pifrec = db.get_pif_record(pif)
+
+ bso = pifrec['bond_slave_of']
+
+ # bond-slave-of is currently a single reference but in principle a
+ # PIF could be a member of several bonds which are not
+ # concurrently attached. Be robust to this possibility.
+ if not bso or bso == "OpaqueRef:NULL":
+ bso = []
+ elif not type(bso) == list:
+ bso = [bso]
+
+ bondrecs = [db.get_bond_record(bond) for bond in bso]
+ bondrecs = [rec for rec in bondrecs if rec]
+
+ return [bond['master'] for bond in bondrecs]
+
+def get_bond_slaves_of_pif(pif):
+ """Returns a list of PIFs which make up the given bonded pif."""
+
+ pifrec = db.get_pif_record(pif)
+ host = pifrec['host']
+
+ bmo = pifrec['bond_master_of']
+ if len(bmo) > 1:
+ raise Error("Bond-master-of contains too many elements")
+
+ if len(bmo) == 0:
+ return []
+
+ bondrec = db.get_bond_record(bmo[0])
+ if not bondrec:
+ raise Error("No bond record for bond master PIF")
+
+ # build a list of slave's pifs
+ slave_pifs = bondrec['slaves']
+
+ # Ensure any currently attached slaves are listed in the opposite order to the order in
+ # which they were attached. The first slave attached must be the last detached since
+ # the bond is using its MAC address.
+ try:
+ attached_slaves = open("/sys/class/net/%s/bonding/slaves" % pifrec['device']).readline().split()
+ for slave in attached_slaves:
+ partial_pifrec = {'host':host, 'device':slave}
+ slave_pif = db.get_pif_by_record(partial_pifrec)
+ slave_pifs.remove(slave_pif)
+ slave_pifs.insert(0, slave_pif)
+ except IOError:
+ pass
+
+ return slave_pifs
+
+def get_vlan_slave_of_pif(pif):
+ """Find the PIF which is the VLAN slave of pif.
+
+Returns the 'physical' PIF underneath the a VLAN PIF @pif."""
+
+ pifrec = db.get_pif_record(pif)
+
+ vlan = pifrec['VLAN_master_of']
+ if not vlan or vlan == "OpaqueRef:NULL":
+ raise Error("PIF is not a VLAN master")
+
+ vlanrec = db.get_vlan_record(vlan)
+ if not vlanrec:
+ raise Error("No VLAN record found for PIF")
+
+ return vlanrec['tagged_PIF']
+
+def get_vlan_masters_of_pif(pif):
+ """Returns a list of PIFs which are VLANs on top of the given pif."""
+
+ pifrec = db.get_pif_record(pif)
+ vlans = [db.get_vlan_record(v) for v in pifrec['VLAN_slave_of']]
+ return [v['untagged_PIF'] for v in vlans if v and db.pif_exists(v['untagged_PIF'])]
+
+def interface_deconfigure_commands(interface):
+ # The use of [!0-9] keeps an interface of 'eth0' from matching
+ # VLANs attached to eth0 (such as 'eth0.123'), which are distinct
+ # interfaces.
+ return ['--del-match=bridge.*.port=%s' % interface,
+ '--del-match=bonding.%s.[!0-9]*' % interface,
+ '--del-match=bonding.*.slave=%s' % interface,
+ '--del-match=vlan.%s.[!0-9]*' % interface,
+ '--del-match=iface.%s.[!0-9]*' % interface]
+
+def run_command(command):
+ log("Running command: " + ' '.join(command))
+ #return
+ if os.spawnl(os.P_WAIT, command[0], *command) != 0:
+ log("Command failed: " + ' '.join(command))
+ return False
+ return True
+
+def down_netdev(interface, deconfigure=True):
+ if not interface_exists(interface):
+ log("down_netdev: interface %s does not exist, ignoring" % interface)
+ return
+ argv = ["/sbin/ifconfig", interface, 'down']
+ if deconfigure:
+ argv += ['0.0.0.0']
+
+ # Kill dhclient.
+ pidfile_name = '/var/run/dhclient-%s.pid' % interface
+ pidfile = None
+ try:
+ pidfile = open(pidfile_name, 'r')
+ os.kill(int(pidfile.readline()), signal.SIGTERM)
+ except:
+ pass
+ if pidfile != None:
+ pidfile.close()
+
+ # Remove dhclient pidfile.
+ try:
+ os.remove(pidfile_name)
+ except:
+ pass
+ run_command(argv)
+
+def up_netdev(interface):
+ run_command(["/sbin/ifconfig", interface, 'up'])
+
+def find_distinguished_pifs(pif):
+ """Returns the PIFs on host that own DNS and the default route.
+The peerdns pif will be the one with pif::other-config:peerdns=true, or the mgmt pif if none have this set.
+The gateway pif will be the one with pif::other-config:defaultroute=true, or the mgmt pif if none have this set.
+
+Note: we prune out the bond master pif (if it exists).
+This is because when we are called to bring up an interface with a bond master, it is implicit that
+we should bring down that master."""
+
+ pifrec = db.get_pif_record(pif)
+ host = pifrec['host']
+
+ pifs_on_host = [ __pif for __pif in db.get_all_pifs() if
+ db.get_pif_record(__pif)['host'] == host and
+ (not __pif in get_bond_masters_of_pif(pif)) ]
+ other_pifs_on_host = [ __pif for __pif in pifs_on_host if __pif != pif ]
+
+ peerdns_pif = None
+ defaultroute_pif = None
+
+ # loop through all the pifs on this host looking for one with
+ # other-config:peerdns = true, and one with
+ # other-config:default-route=true
+ for __pif in pifs_on_host:
+ __pifrec = db.get_pif_record(__pif)
+ __oc = __pifrec['other_config']
+ if __oc.has_key('peerdns') and __oc['peerdns'] == 'true':
+ if peerdns_pif == None:
+ peerdns_pif = __pif
+ else:
+ log('Warning: multiple pifs with "peerdns=true" - choosing %s and ignoring %s' % \
+ (db.get_pif_record(peerdns_pif)['device'], __pifrec['device']))
+ if __oc.has_key('defaultroute') and __oc['defaultroute'] == 'true':
+ if defaultroute_pif == None:
+ defaultroute_pif = __pif
+ else:
+ log('Warning: multiple pifs with "defaultroute=true" - choosing %s and ignoring %s' % \
+ (db.get_pif_record(defaultroute_pif)['device'], __pifrec['device']))
+
+ # If no pif is explicitly specified then use the mgmt pif for peerdns/defaultroute
+ if peerdns_pif == None:
+ peerdns_pif = management_pif
+ if defaultroute_pif == None:
+ defaultroute_pif = management_pif
+
+ return peerdns_pif, defaultroute_pif
+
+def ethtool_settings(oc):
+ # Options for "ethtool -s"
+ settings = []
+ if oc.has_key('ethtool-speed'):
+ val = oc['ethtool-speed']
+ if val in ["10", "100", "1000"]:
+ settings += ['speed', val]
+ else:
+ log("Invalid value for ethtool-speed = %s. Must be 10|100|1000." % val)
+ if oc.has_key('ethtool-duplex'):
+ val = oc['ethtool-duplex']
+ if val in ["10", "100", "1000"]:
+ settings += ['duplex', 'val']
+ else:
+ log("Invalid value for ethtool-duplex = %s. Must be half|full." % val)
+ if oc.has_key('ethtool-autoneg'):
+ val = oc['ethtool-autoneg']
+ if val in ["true", "on"]:
+ settings += ['autoneg', 'on']
+ elif val in ["false", "off"]:
+ settings += ['autoneg', 'off']
+ else:
+ log("Invalid value for ethtool-autoneg = %s. Must be on|true|off|false." % val)
+
+ # Options for "ethtool -K"
+ offload = []
+ for opt in ("rx", "tx", "sg", "tso", "ufo", "gso"):
+ if oc.has_key("ethtool-" + opt):
+ val = oc["ethtool-" + opt]
+ if val in ["true", "on"]:
+ offload += [opt, 'on']
+ elif val in ["false", "off"]:
+ offload += [opt, 'off']
+ else:
+ log("Invalid value for ethtool-%s = %s. Must be on|true|off|false." % (opt, val))
+
+ return settings, offload
+
+def configure_netdev(pif):
+ pifrec = db.get_pif_record(pif)
+ datapath = datapath_name(pif)
+ ipdev = ipdev_name(pif)
+
+ host = pifrec['host']
+ nw = pifrec['network']
+ nwrec = db.get_network_record(nw)
+
+ ifconfig_argv = ['/sbin/ifconfig', ipdev, 'up']
+ gateway = ''
+ if pifrec['ip_configuration_mode'] == "DHCP":
+ pass
+ elif pifrec['ip_configuration_mode'] == "Static":
+ ifconfig_argv += [pifrec['IP']]
+ ifconfig_argv += ['netmask', pifrec['netmask']]
+ gateway = pifrec['gateway']
+ elif pifrec['ip_configuration_mode'] == "None":
+ # Nothing to do.
+ pass
+ else:
+ raise Error("Unknown IP-configuration-mode %s" % pifrec['ip_configuration_mode'])
+
+ oc = {}
+ if pifrec.has_key('other_config'):
+ oc = pifrec['other_config']
+ if oc.has_key('mtu'):
+ int(oc['mtu']) # Check that the value is an integer
+ ifconfig_argv += ['mtu', oc['mtu']]
+
+ run_command(ifconfig_argv)
+
+ (peerdns_pif, defaultroute_pif) = find_distinguished_pifs(pif)
+
+ if peerdns_pif == pif:
+ f = ConfigurationFile('resolv.conf', "/etc")
+ if oc.has_key('domain'):
+ f.write("search %s\n" % oc['domain'])
+ for dns in pifrec['DNS'].split(","):
+ f.write("nameserver %s\n" % dns)
+ f.close()
+ f.apply()
+ f.commit()
+
+ if defaultroute_pif == pif and gateway != '':
+ run_command(['/sbin/ip', 'route', 'replace', 'default',
+ 'via', gateway, 'dev', ipdev])
+
+ if oc.has_key('static-routes'):
+ for line in oc['static-routes'].split(','):
+ network, masklen, gateway = line.split('/')
+ run_command(['/sbin/ip', 'route', 'add',
+ '%s/%s' % (netmask, masklen), 'via', gateway,
+ 'dev', ipdev])
+
+ settings, offload = ethtool_settings(oc)
+ if settings:
+ run_command(['/sbin/ethtool', '-s', ipdev] + settings)
+ if offload:
+ run_command(['/sbin/ethtool', '-K', ipdev] + offload)
+
+ if pifrec['ip_configuration_mode'] == "DHCP":
+ print
+ print "Determining IP information for %s..." % ipdev,
+ argv = ['/sbin/dhclient', '-q',
+ '-lf', '/var/lib/dhclient/dhclient-%s.leases' % ipdev,
+ '-pf', '/var/run/dhclient-%s.pid' % ipdev,
+ ipdev]
+ if run_command(argv):
+ print 'done.'
+ else:
+ print 'failed.'
+
+def modify_config(commands):
+ run_command(['/root/vswitch/bin/cfg-mod', '-F', '/etc/vswitchd.conf']
+ + commands + ['-c'])
+ run_command(['/sbin/service', 'vswitch', 'reload'])
+
+def is_bond_pif(pif):
+ pifrec = db.get_pif_record(pif)
+ return len(pifrec['bond_master_of']) != 0
+
+def configure_bond(pif):
+ pifrec = db.get_pif_record(pif)
+ interface = interface_name(pif)
+ ipdev = ipdev_name(pif)
+ datapath = datapath_name(pif)
+ physdevs = physdev_names(pif)
+
+ argv = ['--del-match=bonding.%s.[!0-9]*' % interface]
+ argv += ["--add=bonding.%s.slave=%s" % (interface, slave)
+ for slave in physdevs]
+
+ # Bonding options.
+ bond_options = {
+ "mode": "balance-slb",
+ "miimon": "100",
+ "downdelay": "200",
+ "updelay": "31000",
+ "use_carrier": "1",
+ }
+ # override defaults with values from other-config whose keys
+ # being with "bond-"
+ oc = pifrec['other_config']
+ overrides = filter(lambda (key,val):
+ key.startswith("bond-"), oc.items())
+ overrides = map(lambda (key,val): (key[5:], val), overrides)
+ bond_options.update(overrides)
+ for (name,val) in bond_options.items():
+ argv += ["--add=bonding.%s.%s=%s" % (interface, name, val)]
+ return argv
+
+def action_up(pif):
+ pifrec = db.get_pif_record(pif)
+
+ interface = interface_name(pif)
+ ipdev = ipdev_name(pif)
+ datapath = datapath_name(pif)
+ physdevs = physdev_names(pif)
+ vlan_slave = None
+ if pifrec['VLAN'] != '-1':
+ vlan_slave = get_vlan_slave_of_pif(pif)
+ if vlan_slave and is_bond_pif(vlan_slave):
+ bond_master = vlan_slave
+ elif is_bond_pif(pif):
+ bond_master = pif
+ else:
+ bond_master = None
+
+ # "ifconfig down" the network device and delete its IP address, etc.
+ down_netdev(ipdev)
+ #if datapath != ipdev:
+ # down_netdev(datapath)
+ if vlan_slave:
+ down_netdev(ipdev_name(vlan_slave), False)
+ for physdev in physdevs:
+ down_netdev(physdev)
+
+ # Remove all keys related to pif and any bond masters linked to PIF.
+ del_ports = [ipdev] + physdevs + get_bond_masters_of_pif(pif)
+ if vlan_slave and bond_master:
+ del_ports += [interface_name(bond_master)]
+
+ # What ports do we need to add to the datapath?
+ #
+ # We definitely need the ipdev, and ordinarily we want the
+ # physical devices too, but for bonds we need the bond as bridge
+ # port.
+ add_ports = [ipdev, datapath]
+ if not bond_master:
+ add_ports += physdevs
+ else:
+ add_ports += [interface_name(bond_master)]
+
+ # What ports do we need to delete first?
+ #
+ # - All the ports that we add, to avoid duplication and to drop
+ # them from another datapath in case they're misassigned.
+ #
+ # - The physical devices, since they will either be in add_ports
+ # or added to the bonding device (see below).
+ #
+ # - The bond masters for pif. (Ordinarily pif shouldn't have any
+ # bond masters. If it does then interface-reconfigure is
+ # implicitly being asked to take them down.)
+ del_ports = add_ports + physdevs + get_bond_masters_of_pif(pif)
+
+ # Now modify the vswitchd config file.
+ argv = []
+ for port in set(del_ports):
+ argv += interface_deconfigure_commands(port)
+ for port in set(add_ports):
+ argv += ['--add=bridge.%s.port=%s' % (datapath, port)]
+ if vlan_slave:
+ argv += ['--add=vlan.%s.tag=%s' % (ipdev, pifrec['VLAN'])]
+ argv += ['--add=iface.%s.internal=true' % (ipdev)]
+ if bond_master:
+ argv += configure_bond(bond_master)
+ modify_config(argv)
+
+ # Configure network devices.
+ configure_netdev(pif)
+
+ # Bring up VLAN slave and bond slaves.
+ if vlan_slave:
+ up_netdev(ipdev_name(vlan_slave))
+ for physdev in physdevs:
+ up_netdev(physdev)
+
+ # Update /etc/issue (which contains the IP address of the management interface)
+ os.system("/sbin/update-issue")
+
+def action_down(pif):
+ rec = db.get_pif_record(pif)
+ interface = interface_name(pif)
+ bridge = bridge_name(pif)
+ ipdev = ipdev_name(pif)
+
+ argv = []
+ if rec['VLAN'] != '-1':
+ # Get rid of the VLAN device itself.
+ down_netdev(ipdev)
+ argv += interface_deconfigure_commands(ipdev)
+
+ # If the VLAN's slave is attached, stop here.
+ slave = get_vlan_slave_of_pif(pif)
+ if db.get_pif_record(slave)['currently_attached']:
+ log("VLAN slave is currently attached")
+ modify_config(argv)
+ return
+
+ # If the VLAN's slave has other VLANs that are attached, stop here.
+ masters = get_vlan_masters_of_pif(slave)
+ for m in masters:
+ if m != pif and db.get_pif_record(m)['currently_attached']:
+ log("VLAN slave has other master %s" % interface_naem(m))
+ modify_config(argv)
+ return
+
+ # Otherwise, take down the VLAN's slave too.
+ log("No more masters, bring down vlan slave %s" % interface_name(slave))
+ pif = slave
+ else:
+ # Stop here if this PIF has attached VLAN masters.
+ vlan_masters = get_vlan_masters_of_pif(pif)
+ log("VLAN masters of %s - %s" % (rec['device'], [interface_name(m) for m in vlan_masters]))
+ for m in vlan_masters:
+ if db.get_pif_record(m)['currently_attached']:
+ log("Leaving %s up due to currently attached VLAN master %s" % (interface, interface_name(m)))
+ return
+
+ # pif is now either a bond or a physical device which needs to be
+ # brought down. pif might have changed so re-check all its attributes.
+ rec = db.get_pif_record(pif)
+ interface = interface_name(pif)
+ bridge = bridge_name(pif)
+ ipdev = ipdev_name(pif)
+
+
+ bond_slaves = get_bond_slaves_of_pif(pif)
+ log("bond slaves of %s - %s" % (rec['device'], [interface_name(s) for s in bond_slaves]))
+ for slave in bond_slaves:
+ slave_interface = interface_name(slave)
+ log("bring down bond slave %s" % slave_interface)
+ argv += interface_deconfigure_commands(slave_interface)
+ down_netdev(slave_interface)
+
+ argv += interface_deconfigure_commands(ipdev)
+ down_netdev(ipdev)
+
+ argv += ['--del-match', 'bridge.%s.*' % datapath_name(pif)]
+ argv += ['--del-match', 'bonding.%s.[!0-9]*' % interface]
+ modify_config(argv)
+
+def action_rewrite(pif):
+ pifrec = db.get_pif_record(pif)
+ db.save(dbcache_file, {'host': pifrec['host']})
+
+def main(argv=None):
+ global output_directory, management_pif
+
+ session = None
+ pif_uuid = None
+ pif = None
+
+ force_interface = None
+ force_management = False
+
+ if argv is None:
+ argv = sys.argv
+
+ try:
+ try:
+ shortops = "h"
+ longops = [ "output-directory=",
+ "pif=", "pif-uuid=",
+ "session=",
+ "force=",
+ "force-interface=",
+ "management",
+ "test-mode",
+ "device=", "mode=", "ip=", "netmask=", "gateway=",
+ "help" ]
+ arglist, args = getopt.gnu_getopt(argv[1:], shortops, longops)
+ except getopt.GetoptError, msg:
+ raise Usage(msg)
+
+ force_rewrite_config = {}
+
+ for o,a in arglist:
+ if o == "--output-directory":
+ output_directory = a
+ elif o == "--pif":
+ pif = a
+ elif o == "--pif-uuid":
+ pif_uuid = a
+ elif o == "--session":
+ session = a
+ elif o == "--force-interface" or o == "--force":
+ force_interface = a
+ elif o == "--management":
+ force_management = True
+ elif o in ["--device", "--mode", "--ip", "--netmask", "--gateway"]:
+ force_rewrite_config[o[2:]] = a
+ elif o == "-h" or o == "--help":
+ print __doc__ % {'command-name': os.path.basename(argv[0])}
+ return 0
+
+ if not debug_mode():
+ syslog.openlog(os.path.basename(argv[0]))
+ log("Called as " + str.join(" ", argv))
+ if len(args) < 1:
+ raise Usage("Required option <action> not present")
+ if len(args) > 1:
+ raise Usage("Too many arguments")
+
+ action = args[0]
+ # backwards compatibility
+ if action == "rewrite-configuration": action = "rewrite"
+
+ if output_directory and ( session or pif ):
+ raise Usage("--session/--pif cannot be used with --output-directory")
+ if ( session or pif ) and pif_uuid:
+ raise Usage("--session/--pif and --pif-uuid are mutually exclusive.")
+ if ( session and not pif ) or ( not session and pif ):
+ raise Usage("--session and --pif must be used together.")
+ if force_interface and ( session or pif or pif_uuid ):
+ raise Usage("--force is mutually exclusive with --session, --pif and --pif-uuid")
+ if len(force_rewrite_config) and not (force_interface and action == "rewrite"):
+ raise Usage("\"--force rewrite\" needed for --device, --mode, --ip, --netmask, and --gateway")
+
+ global db
+ if force_interface:
+ log("Force interface %s %s" % (force_interface, action))
+
+ if action == "rewrite":
+ action_force_rewrite(force_interface, force_rewrite_config)
+ else:
+ db = DatabaseCache(cache_file=dbcache_file)
+ host = db.extras['host']
+ pif = db.get_pif_by_bridge(host, force_interface)
+
+ if action == "up":
+ action_up(pif)
+ elif action == "down":
+ action_down(pif)
+ else:
+ raise Usage("Unknown action %s" % action)
+ else:
+ db = DatabaseCache(session_ref=session)
+
+ if pif_uuid:
+ pif = db.get_pif_by_uuid(pif_uuid)
+
+ if not pif:
+ raise Usage("No PIF given")
+
+ if force_management:
+ # pif is going to be the management pif
+ management_pif = pif
+ else:
+ # pif is not going to be the management pif.
+ # Search DB cache for pif on same host with management=true
+ pifrec = db.get_pif_record(pif)
+ host = pifrec['host']
+ management_pif = db.get_management_pif(host)
+
+ log_pif_action(action, pif)
+
+ if not check_allowed(pif):
+ return 0
+
+ if action == "up":
+ action_up(pif)
+ elif action == "down":
+ action_down(pif)
+ elif action == "rewrite":
+ action_rewrite(pif)
+ else:
+ raise Usage("Unknown action %s" % action)
+
+ except Usage, err:
+ print >>sys.stderr, err.msg
+ print >>sys.stderr, "For help use --help."
+ return 2
+ except Error, err:
+ log(err.msg)
+ return 1
+
+ return 0
+
+if __name__ == "__main__":
+ rc = 1
+ try:
+ rc = main()
+ except:
+ ex = sys.exc_info()
+ err = traceback.format_exception(*ex)
+ for exline in err:
+ log(exline)
+
+ if not debug_mode():
+ syslog.closelog()
+
+ sys.exit(rc)
--- /dev/null
+# Copyright (c) Citrix Systems 2008. All rights reserved.
+# xsconsole is proprietary software.
+#
+# Xen, the Xen logo, XenCenter, XenMotion are trademarks or registered
+# trademarks of Citrix Systems, Inc., in the United States and other
+# countries.
+
+# Copyright (c) 2009 Nicira Networks.
+
+import logging
+log = logging.getLogger("vswitch-cfg-update")
+logging.basicConfig(filename="/var/log/vswitch-xsplugin.log", level=logging.DEBUG)
+
+import os
+import subprocess
+
+cfg_mod="/root/vswitch/bin/cfg-mod"
+vswitchd_cfg_filename="/etc/vswitchd.conf"
+
+if __name__ == "__main__":
+ raise Exception("This script is a plugin for xsconsole and cannot run independently")
+
+from XSConsoleStandard import *
+
+class NiciraService:
+ service = {}
+
+ def __init__(self, name, processname=None):
+ self.name = name
+ self.processname = processname
+ if self.processname == None:
+ self.processname = name
+
+ def _execCmd(self, cmd):
+ pipe = subprocess.PIPE
+ return subprocess.Popen(cmd, stdin=pipe, stdout=pipe, stderr=pipe)
+
+ def status(self):
+ cmd = [ "service", self.name, "status" ]
+ try:
+ p = self._execCmd(cmd)
+ output = p.communicate()[0]
+ except StandardError, e:
+ log.error("Subprocess error: " + str(e))
+ return "<unknown>"
+ if output == None:
+ return "<unknown>"
+ for l in output.split("\n"):
+ if self.processname not in l:
+ continue
+ elif "running" in l:
+ return "Running"
+ elif "stop" in l:
+ return "Stopped"
+ else:
+ return "<unknown>"
+ return "<unknown>"
+
+ def restart(self):
+ cmd = [ "service", self.name, "restart" ]
+ try:
+ p = self._execCmd(cmd)
+ p.communicate()
+ except StandardError, e:
+ log.error("Subprocess error: ", str(e))
+
+ @classmethod
+ def Inst(cls, name, processname=None):
+ key = name
+ if processname != None:
+ key = key + "-" + processname
+ if name not in cls.service:
+ cls.service[key] = NiciraService(name, processname)
+ return cls.service[key]
+
+class VSwitchConfig:
+
+ @staticmethod
+ def Get(key):
+ cmd = [cfg_mod, "--config-file=" + vswitchd_cfg_filename, "-q", key]
+ output = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()
+ if len(output) == 0 or output[0] == None:
+ output = ""
+ else:
+ output = output[0].strip()
+ return output
+
+
+class NiciraControllerDialogue(Dialogue):
+ def __init__(self):
+ Dialogue.__init__(self)
+ data=Data.Inst()
+
+ self.hostsInPool = 0
+ self.hostsUpdated = 0
+
+ pool = data.pools().values()[0]
+ try:
+ self.controller = pool["other_config"]["niciraController"]
+ except KeyError, e:
+ self.controller = ""
+
+ choiceDefs = [
+ ChoiceDef(Lang("Set pool-wide controller"),
+ lambda: self.getController()),
+ ChoiceDef(Lang("Delete pool-wide controller"),
+ lambda: self.deleteController()),
+ ChoiceDef(Lang("Resync server controller config"),
+ lambda: self.syncController()),
+# ChoiceDef(Lang("Restart vswitchd"),
+# lambda: self.restartService("vswitch")),
+# ChoiceDef(Lang("Restart brcompatd"),
+# lambda: self.restartService("vswitch-brcompatd"))
+ ]
+ self.menu = Menu(self, None, Lang("Configure Nicira VSwitch"), choiceDefs)
+
+ self.ChangeState("INITIAL")
+
+ def BuildPane(self):
+ pane = self.NewPane(DialoguePane(self.parent))
+ pane.TitleSet(Lang("Configure Nicira VSwitch"))
+ pane.AddBox()
+
+ def ChangeState(self, inState):
+ self.state = inState
+ self.BuildPane()
+ self.UpdateFields()
+
+ def UpdateFields(self):
+ self.Pane().ResetPosition()
+ getattr(self, "UpdateFields" + self.state)() # Dispatch method named 'UpdateFields'+self.state
+
+ def UpdateFieldsINITIAL(self):
+ pane = self.Pane()
+ pane.AddTitleField(Lang("Select an action"))
+ pane.AddMenuField(self.menu)
+ pane.AddKeyHelpField( { Lang("<Enter>") : Lang("OK"), Lang("<Esc>") : Lang("Cancel") } )
+
+ def UpdateFieldsGETCONTROLLER(self):
+ pane = self.Pane()
+ pane.ResetFields()
+
+ pane.AddTitleField(Lang("Enter IP address of controller"))
+ pane.AddInputField(Lang("Address", 16), self.controller, "address")
+ pane.AddKeyHelpField( { Lang("<Enter>") : Lang("OK"), Lang("<Esc>") : Lang("Exit") } )
+ if pane.CurrentInput() is None:
+ pane.InputIndexSet(0)
+
+ def UpdateFieldsCALLPLUGIN(self):
+ pane = self.Pane()
+ pane.ResetFields()
+ pane.AddTitleField(Lang("Updating members of pool"))
+ progress = "%d / %d" % (self.hostsUpdated, self.hostsInPool)
+ pane.AddWrappedTextField(Lang("Progress", 16) + progress)
+
+ def HandleKey(self, inKey):
+ handled = False
+ if hasattr(self, "HandleKey" + self.state):
+ handled = getattr(self, "HandleKey" + self.state)(inKey)
+ if not handled and inKey == 'KEY_ESCAPE':
+ Layout.Inst().PopDialogue()
+ handled = True
+ return handled
+
+ def HandleKeyINITIAL(self, inKey):
+ return self.menu.HandleKey(inKey)
+
+ def HandleKeyGETCONTROLLER(self, inKey):
+ pane = self.Pane()
+ if pane.CurrentInput() is None:
+ pane.InputIndexSet(0)
+ if inKey == 'KEY_ENTER':
+ inputValues = pane.GetFieldValues()
+ self.controller = inputValues['address']
+ self.SetController(self.controller)
+ Layout.Inst().PopDialogue()
+ self.ChangeState("INITIAL")
+ return True
+ else:
+ return pane.CurrentInput().HandleKey(inKey)
+
+ def restartService(self, name):
+ s = NiciraService.Inst(name)
+ s.restart()
+ Layout.Inst().PopDialogue()
+
+ def getController(self):
+ self.ChangeState("GETCONTROLLER")
+ self.Pane().InputIndexSet(0)
+
+ def deleteController(self):
+ self.controller = ""
+ self.SetController(None)
+ Layout.Inst().PopDialogue()
+
+ def syncController(self):
+ Task.Sync(lambda s: self._updateThisServer(s))
+ Layout.Inst().PopDialogue()
+
+ def SetController(self, ip):
+ self.hostsInPool = 0
+ self.hostsUpdated = 0
+ self.ChangeState("CALLPLUGIN")
+ Task.Sync(lambda s: self._modifyPoolConfig(s, "niciraController", ip))
+ # Should be done asynchronously, maybe with an external script?
+ Task.Sync(lambda s: self._updateActiveServers(s))
+
+ def _modifyPoolConfig(self, session, key, value):
+ """Modify pool configuration.
+
+ If value == None then delete key, otherwise set key to value."""
+ pools = session.xenapi.pool.get_all()
+ # We assume there is only ever one pool...
+ if len(pools) == 0:
+ log.error("No pool for host.")
+ raise XenAPIPlugin.Failure("NO_POOL_FOR_HOST", [])
+ if len(pools) > 1:
+ log.error("More than one pool for host.")
+ raise XenAPIPlugin.Failure("MORE_THAN_ONE_POOL_FOR_HOST", [])
+ session.xenapi.pool.remove_from_other_config(pools[0], key)
+ if value != None:
+ session.xenapi.pool.add_to_other_config(pools[0], key, value)
+ Data.Inst().Update()
+
+ def _updateActiveServers(self, session):
+ hosts = session.xenapi.host.get_all()
+ self.hostsUpdated = 0
+ self.hostsInPool = len(hosts)
+ self.UpdateFields()
+ for host in hosts:
+ session.xenapi.host.call_plugin(host, "vswitch-cfg-update", "update", {})
+ self.hostsUpdated = self.hostsUpdated + 1
+ self.UpdateFields()
+
+ def _updateThisServer(self, session):
+ data = Data.Inst()
+ host = data.host.opaqueref()
+ session.xenapi.host.call_plugin(host, "vswitch-cfg-update", "update", {})
+
+
+class XSFeatureNiciraVSwitch:
+
+ @classmethod
+ def StatusUpdateHandler(cls, inPane):
+ data = Data.Inst()
+
+ inPane.AddTitleField(Lang("Nicira VSwitch"))
+
+ inPane.NewLine()
+
+ host = data.host()
+ try:
+ versionStr = host["other_config"]["niciraSwitchVersion"]
+ except KeyError, e:
+ versionStr = "<Unknown>"
+ inPane.AddStatusField(Lang("Version", 20), versionStr)
+
+ inPane.NewLine()
+ pool = data.pools().values()[0]
+ try:
+ dbController = pool["other_config"]["niciraController"]
+ except KeyError, e:
+ dbController = ""
+ if dbController == "":
+ dbController = Lang("<None>")
+ inPane.AddStatusField(Lang("Controller (config)", 20), dbController)
+ controller = VSwitchConfig.Get("mgmt.controller")
+ if controller == "":
+ controller = Lang("<None>")
+ elif controller[0:4] == "ssl:":
+ controller = controller[4:]
+ inPane.AddStatusField(Lang("Controller (in-use)", 20), controller)
+
+ inPane.NewLine()
+ inPane.AddStatusField(Lang("vswitchd status", 20),
+ NiciraService.Inst("vswitch", "vswitchd").status())
+ inPane.AddStatusField(Lang("brcompatd status", 20),
+ NiciraService.Inst("vswitch", "brcompatd").status())
+
+ inPane.AddKeyHelpField( {
+ Lang("<Enter>") : Lang("Reconfigure"),
+ Lang("<F5>") : Lang("Refresh")
+ })
+
+ @classmethod
+ def ActivateHandler(cls):
+ DialogueUtils.AuthenticatedOnly(lambda: Layout.Inst().PushDialogue(NiciraControllerDialogue()))
+
+ def Register(self):
+ Importer.RegisterNamedPlugIn(
+ self,
+ 'NiciraVSwitch', # Key of this plugin for replacement, etc.
+ {
+ 'menuname' : 'MENU_NETWORK',
+ 'menupriority' : 800,
+ 'menutext' : Lang('Nicira VSwitch') ,
+ 'statusupdatehandler' : self.StatusUpdateHandler,
+ 'activatehandler' : self.ActivateHandler
+ }
+ )
+
+# Register this plugin when module is imported
+XSFeatureNiciraVSwitch().Register()
--- /dev/null
+# Spec file for vswitch and related programs.
+
+# Copyright (C) 2009 Nicira Networks, Inc.
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved. This file is offered as-is,
+# without warranty of any kind.
+
+# When building, the rpmbuild command line should define
+# vswitch_version, xen_version, and build_number using -D arguments.
+# for example:
+#
+# rpmbuild -D "vswitch_version 0.8.9~1+build123" -D "xen_version 2.6.18-128.1.1.el5.xs5.1.0.483.1000xen" -D "build_number --with-build-number=123" -bb /usr/src/redhat/SPECS/vswitch-xen.spec
+#
+%define version %{vswitch_version}-%{xen_version}
+%define _prefix /root/vswitch
+
+Name: vswitch
+Summary: Virtual switch
+Group: System Environment/Daemons
+URL: http://www.vswitch.org/
+Version: %{vswitch_version}
+License: GPL3
+Release: 1
+Source: openvswitch+ext-%{vswitch_version}.tar.gz
+Buildroot: /tmp/vswitch-xen-rpm
+
+%description
+The vswitch provides standard network briding functions augmented with
+support for the OpenFlow protocol for remote per-flow control of
+traffic.
+
+%prep
+%setup -q -n openvswitch+ext-%{vswitch_version}
+
+%build
+./configure --prefix=%{_prefix} --localstatedir=%{_localstatedir} --with-l26=/lib/modules/%{xen_version}/build --enable-ssl %{build_number}
+make
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT prefix=%{_prefix}
+install -d -m 755 $RPM_BUILD_ROOT/etc
+install -d -m 755 $RPM_BUILD_ROOT/etc/init.d
+install -m 755 xenserver/etc_init.d_vswitch \
+ $RPM_BUILD_ROOT/etc/init.d/vswitch
+install -m 755 xenserver/etc_init.d_vswitch-xapi-update \
+ $RPM_BUILD_ROOT/etc/init.d/vswitch-xapi-update
+install -d -m 755 $RPM_BUILD_ROOT/etc/sysconfig
+install -m 755 xenserver/etc_sysconfig_vswitch.example \
+ $RPM_BUILD_ROOT/etc/sysconfig/vswitch.example
+install -d -m 755 $RPM_BUILD_ROOT/etc/logrotate.d
+install -m 755 xenserver/etc_logrotate.d_vswitch \
+ $RPM_BUILD_ROOT/etc/logrotate.d/vswitch
+install -d -m 755 $RPM_BUILD_ROOT/etc/profile.d
+install -m 755 xenserver/etc_profile.d_vswitch.sh \
+ $RPM_BUILD_ROOT/etc/profile.d/vswitch.sh
+install -d -m 755 $RPM_BUILD_ROOT/etc/xapi.d/plugins
+install -m 755 xenserver/etc_xapi.d_plugins_vswitch-cfg-update \
+ $RPM_BUILD_ROOT/etc/xapi.d/plugins/vswitch-cfg-update
+install -d -m 755 $RPM_BUILD_ROOT%{_prefix}/scripts
+install -m 755 xenserver/opt_xensource_libexec_interface-reconfigure \
+ $RPM_BUILD_ROOT%{_prefix}/scripts/interface-reconfigure
+install -m 755 xenserver/etc_xensource_scripts_vif \
+ $RPM_BUILD_ROOT%{_prefix}/scripts/vif
+install -m 755 \
+ xenserver/usr_lib_xsconsole_plugins-base_XSFeatureNiciraVSwitch.py \
+ $RPM_BUILD_ROOT%{_prefix}/scripts/XSFeatureNiciraVSwitch.py
+
+install -d -m 755 $RPM_BUILD_ROOT%{_prefix}/kernel_modules
+find datapath/linux-2.6 -name *.ko -exec install -m 755 \{\} $RPM_BUILD_ROOT%{_prefix}/kernel_modules/ \;
+
+# Get rid of stuff we don't want to make RPM happy.
+rm -rf $RPM_BUILD_ROOT/root/vswitch/bin/controller \
+ $RPM_BUILD_ROOT/root/vswitch/bin/ovs-* \
+ $RPM_BUILD_ROOT/root/vswitch/bin/secchan \
+ $RPM_BUILD_ROOT/root/vswitch/bin/wdt \
+ $RPM_BUILD_ROOT/root/vswitch/sbin/ovs-monitor \
+ $RPM_BUILD_ROOT/root/vswitch/share/man/man8/controller.8 \
+ $RPM_BUILD_ROOT/root/vswitch/share/man/man8/ovs-*.8 \
+ $RPM_BUILD_ROOT/root/vswitch/share/man/man8/secchan.8 \
+ $RPM_BUILD_ROOT/root/vswitch/share/openvswitch
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%pre
+if [ ! -f /etc/xensource-inventory ]; then
+ printf "XenSource inventory not present in /etc/xensource-inventory"
+ exit 1
+fi
+
+if [ "$1" = "1" ]; then
+ if ! md5sum -c --status <<EOF
+b8e9835862ef1a9cec2a3f477d26c989 /etc/xensource/scripts/vif
+51970ad613a3996d5997e18e44db47da /opt/xensource/libexec/interface-reconfigure
+EOF
+ then
+ printf "\nThe original XenServer scripts replaced by this package\n"
+ printf "are different than expected. This could lead to unexpected\n"
+ printf "behavior of your server. Unless you are sure you know what\n"
+ printf "you are doing, it is highly recomended that you remove this\n"
+ printf "package immediately after the install completes, which\n"
+ printf "will restore the XenServer scripts that you were previously\n"
+ printf "using.\n\n"
+ fi
+fi
+
+
+%post
+source /etc/xensource-inventory
+
+xe host-param-set \
+ "other-config:niciraSwitchVersion=%{version}" uuid="$INSTALLATION_UUID"
+
+# Ensure vswitchd.conf exists
+touch /etc/vswitchd.conf
+
+# Replace original XenServer files
+mkdir -p %{_prefix}/xs-original \
+ || printf "Could not create script backup directory.\n"
+for f in \
+ /opt/xensource/libexec/interface-reconfigure \
+ /etc/xensource/scripts/vif
+do
+ s=$(basename "$f")
+ t=$(readlink "$f")
+ if [ "$t" != "%{_prefix}/scripts/$s" ]; then
+ mv "$f" %{_prefix}/xs-original/ \
+ || printf "Could not save original XenServer $s script\n"
+ ln -s "%{_prefix}/scripts/$s" "$f" \
+ || printf "Could not link to Nicira $s script\n"
+ fi
+done
+
+# Install xsconsole plugin
+plugin=$(readlink /usr/lib/xsconsole/plugins-base/XSFeatureNiciraVSwitch.py)
+if [ "$plugin" != "/root/vswitch/scripts/XSFeatureNiciraVSwitch.py" ]; then
+ rm -f /usr/lib/xsconsole/plugins-base/XSFeatureNiciraVSwitch.py
+ ln -s /root/vswitch/scripts/XSFeatureNiciraVSwitch.py /usr/lib/xsconsole/plugins-base/ || printf "Could not link to Nicira xsconsole plugin.\n"
+fi
+
+# Modify conf files for compatibility with our interface-reconfigure
+for pif in $(xe pif-list host-uuid=$INSTALLATION_UUID params=uuid | awk '{print $5}'); do
+ /opt/xensource/libexec/interface-reconfigure --pif-uuid $pif rewrite
+done
+
+# Ensure all required services are set to run
+for s in vswitch vswitch-xapi-update; do
+ if chkconfig --list $s >/dev/null 2>&1; then
+ chkconfig --del $s || printf "Could not remove $s init script."
+ fi
+ chkconfig --add $s || printf "Could not add $s init script."
+ chkconfig $s on || printf "Could not enable $s init script."
+done
+
+if [ "$1" = "1" ]; then # $1 = 2 for upgrade
+ printf "\nYou MUST reboot the server NOW to complete the change to the\n"
+ printf "the Nicira vswitch. Attmepts to modify networking on the server\n"
+ printf "or any hosted VM will fail until after the reboot and could\n"
+ printf "leave the server in an state requiring manual recovery.\n\n"
+else
+ printf "\nTo use the new Nicira vswitch, you should reboot the server\n"
+ printf "now. Failure to do so may result in incorrect operation.\n\n"
+fi
+
+%preun
+if [ "$1" = "0" ]; then # $1 = 1 for upgrade
+ for s in vswitch vswitch-xapi-update; do
+ chkconfig --del $s || printf "Could not remove $s init script."
+ done
+ # Restore standard Xen interface-reconfigure compatible conf files
+ source /etc/xensource-inventory
+ for pif in $(xe pif-list host-uuid=$INSTALLATION_UUID params=uuid | awk '{print $5}'); do
+ %{_prefix}/xs-original/interface-reconfigure --pif-uuid $pif rewrite
+ done
+fi
+
+
+%postun
+if [ "$1" = "0" ]; then # $1 = 1 for upgrade
+
+ rm -f /usr/lib/xsconsole/plugins-base/XSFeatureNiciraVSwitch.py \
+ /usr/lib/xsconsole/plugins-base/XSFeatureNiciraVSwitch.pyc \
+ /usr/lib/xsconsole/plugins-base/XSFeatureNiciraVSwitch.pyo \
+ || printf "Could not remove Nicira xsconsole plugin.\n"
+
+ # Restore original XenServer scripts
+ for f in \
+ /opt/xensource/libexec/interface-reconfigure \
+ /etc/xensource/scripts/vif
+ do
+ s=$(basename "$f")
+ if [ ! -f "%{_prefix}/xs-original/$s" ]; then
+ printf "Original XenServer $s script not present in %{_prefix}/xs-original\n"
+ printf "Could not restore original XenServer script.\n"
+ else
+ (rm -f "$f" \
+ && mv "%{_prefix}/xs-original/$s" "$f") \
+ || printf "Could not restore original XenServer $s script.\n"
+ fi
+ done
+
+ find %{_prefix} -type d -depth -exec rmdir \{\} \; \
+ || printf "Could not remove Nicira vswitch install directory.\n"
+
+ # Remove all configuration and log files
+ rm -f /etc/vswitchd.conf
+ rm -f /etc/sysconfig/vswitch
+ rm -f /var/log/vswitch*
+ rm -f /etc/vswitchd.cacert
+
+ if [ ! -f /etc/xensource-inventory ]; then
+ printf "XenSource inventory not present in /etc/xensource-inventory\n"
+ printf "Could not remove niciraSwitchVersion from XAPI database.\n"
+ exit 1
+ else
+ source /etc/xensource-inventory
+ xe host-param-remove \
+ param-name=other-config param-key=niciraSwitchVersion \
+ uuid="$INSTALLATION_UUID"
+ fi
+
+ printf "\nYou MUST reboot the server now to complete the change to\n"
+ printf "standard Xen networking. Attempts to modify networking on the\n"
+ printf "server or any hosted VM will fail until after the reboot and\n"
+ printf "could leave the server in a state requiring manual recovery.\n\n"
+fi
+
+
+%files
+%defattr(-,root,root)
+/etc/init.d/vswitch
+/etc/init.d/vswitch-xapi-update
+/etc/xapi.d/plugins/vswitch-cfg-update
+/etc/sysconfig/vswitch.example
+/etc/logrotate.d/vswitch
+/etc/profile.d/vswitch.sh
+/root/vswitch/kernel_modules/brcompat_mod.ko
+/root/vswitch/kernel_modules/openvswitch_mod.ko
+/root/vswitch/kernel_modules/veth_mod.ko
+/root/vswitch/scripts/interface-reconfigure
+/root/vswitch/scripts/vif
+/root/vswitch/scripts/XSFeatureNiciraVSwitch.py
+# Following two files are generated automatically by rpm. We don't
+# really need them and they won't be used on the XenServer, but there
+# isn't an obvious place to get rid of them since they are generated
+# after the install script runs. Since they are small, we just
+# include them.
+/root/vswitch/scripts/XSFeatureNiciraVSwitch.pyc
+/root/vswitch/scripts/XSFeatureNiciraVSwitch.pyo
+/root/vswitch/sbin/brcompatd
+/root/vswitch/sbin/vswitchd
+/root/vswitch/bin/cfg-mod
+/root/vswitch/bin/dpctl
+/root/vswitch/bin/vlogconf
+/root/vswitch/share/man/man5/vswitchd.conf.5
+/root/vswitch/share/man/man8/brcompatd.8
+/root/vswitch/share/man/man8/cfg-mod.8
+/root/vswitch/share/man/man8/dpctl.8
+/root/vswitch/share/man/man8/vlogconf.8
+/root/vswitch/share/man/man8/vswitchd.8