Permalink
Browse files

Initial commit

fbshipit-source-id: c824e9b6ff4ca70ba082ab9264610f74eb685426
  • Loading branch information...
FBShipIt
FBShipIt committed Aug 2, 2016
0 parents commit cd344d77fc40da9a8ad918f4a141fbee2d9d1a8c
@@ -0,0 +1,5 @@
* Vinnie Magro (Production Engineer Intern 2016)
* Angelo Failla (Production Engineer)
* Roman Gushchin (Production Engineer)
* Mateusz Kaczanowski (Production Engineer)
* Jake Bunce (Network Engineer)
@@ -0,0 +1,38 @@
# Contributing to `dhcplb`
We want to make contributing to this project as easy and transparent as
possible.
## Pull Requests
We actively welcome your pull requests.
1. Fork the repo and create your branch from `master`.
2. If you've added code that should be tested, add tests.
3. If you've changed APIs, update the documentation.
4. Ensure the test suite passes.
5. Make sure your code lints.
6. If you haven't already, complete the Contributor License Agreement ("CLA").
## Contributor License Agreement ("CLA")
In order to accept your pull request, we need you to submit a CLA. You only need
to do this once to work on any of Facebook's open source projects.
Complete your CLA here: <https://code.facebook.com/cla>
## Issues
We use GitHub issues to track public bugs. Please ensure your description is
clear and has sufficient instructions to be able to reproduce the issue.
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe
disclosure of security bugs. In those cases, please go through the process
outlined on that page and do not file a public issue.
## License
By contributing to `dhcplb`, you agree that your contributions will be licensed
under the LICENSE file in the root directory of this source tree.
# I don't want to make a pull request!
We love pull requests, but it's not necessary to write code to contribute. If
for any reason you can't make a pull request (e.g. you just want to suggest us
an improvement), let us know.
[Create an issue](https://help.github.com/articles/creating-an-issue/)
on the `dhcplb` issue tracker and we will review your request.
30 LICENSE
@@ -0,0 +1,30 @@
BSD License
For dhcplb software
Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name Facebook nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 PATENTS
@@ -0,0 +1,33 @@
Additional Grant of Patent Rights Version 2
"Software" means the dhcplb software distributed by Facebook, Inc.
Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software
("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable
(subject to the termination provision below) license under any Necessary
Claims, to make, have made, use, sell, offer to sell, import, and otherwise
transfer the Software. For avoidance of doubt, no license is granted under
Facebook’s rights in any patent claims that are infringed by (i) modifications
to the Software made by you or any third party or (ii) the Software in
combination with any software or other technology.
The license granted hereunder will terminate, automatically and without notice,
if you (or any of your subsidiaries, corporate affiliates or agents) initiate
directly or indirectly, or take a direct financial interest in, any Patent
Assertion: (i) against Facebook or any of its subsidiaries or corporate
affiliates, (ii) against any party if such Patent Assertion arises in whole or
in part from any software, technology, product or service of Facebook or any of
its subsidiaries or corporate affiliates, or (iii) against any party relating
to the Software. Notwithstanding the foregoing, if Facebook or any of its
subsidiaries or corporate affiliates files a lawsuit alleging patent
infringement against you in the first instance, and you respond by filing a
patent infringement counterclaim in that lawsuit against that party that is
unrelated to the Software, the license granted hereunder will not terminate
under section (i) of this paragraph due to such counterclaim.
A "Necessary Claim" is a claim of a patent owned by Facebook that is
necessarily infringed by the Software standing alone.
A "Patent Assertion" is any lawsuit or other action alleging direct, indirect,
or contributory infringement or inducement to infringe any patent, including a
cross-claim or counterclaim.
178 README.md
@@ -0,0 +1,178 @@
# What is dhcplb?
`dhcplb` is Facebook's implementation of a DHCP v4/v6 relayer with load
balancing capabilities.
Facebook currently uses it in production, and it's deployed at global scale
across all of our data centers.
# Why did you do that?
Facebook uses DHCP to provide network configuration to bare-metal machines at
provisioning phase and to assign IPs to out-of-band interfaces.
`dhcplb` was created because the previous infrastructure surrounding DHCP led
to very unbalanced load across the DHCP servers in a region when simply using
Anycast+ECMP alone (for example 1 server out of 10 would receive >65% of
requests).
Facebook's DHCP infrastructure was [presented at SRECon15 Ireland](https://www.usenix.org/conference/srecon15europe/program/presentation/failla).
# Why not use an existing load balancer?
* All the relayer implementations available on the internet lack the load
balancing functionality.
* Having control of the code gives you the the ability to
* perform A/B testing on new builds of our DHCP server
* implement override mechanism
* implement anything additional you need
# How do you use `dhcplb` at Facebook?
This picture shows how we have deployed `dhcplb` in our production
infrastructure:
![DHCPLB deployed at Facebook](/docs/dhcplb-fb-deployment.jpg)
TORs (Top of Rack switch) at Facebook run DHCP relayers, these relayers are
responsible for relaying broadcast DHCP traffic (DISCOVERY and SOLICIT
messages) originating within their racks to anycast VIPs, one DHCPv4 and one
for DHCPv6.
In a Cisco switch the configuration would look like this:
```
ip helper-address 10.127.255.67
ipv6 dhcp relay destination 2401:db00:eef0:a67::
```
We have a bunch of `dhcplb` [Tupperware](https://blog.docker.com/2014/07/dockercon-video-containerized-deployment-at-facebook/) instances in every region listening on
those VIPs.
They are responsible for received traffic relayed by TORs agents and load
balancing them amongst the actual KEA dhcp servers distributed across clusters
in that same region.
The configuration for `dhcplb` consists of 3 files:
* json config file: contains the main configuration for the server as explained
in the [Getting Started](docs/getting-started.md) section
* host lists file: contains a list of dhcp servers, one per line, those are
the servers `dhcplb` will try to balance on
* overrides file: a file containing per mac overrides. See
[Getting Started](docs/getting-started.md) section.
# What does it support?
`dhcplb` is an implementation of a DHCP relay agent, (mostly) implementing the
following RFCs:
* [RFC 2131](https://tools.ietf.org/html/rfc2131) (DHCPv4)
* [RFC 3315](https://tools.ietf.org/html/rfc3315) (DHCPv6)
Note that currently `dhcplb` does not support relaying broadcasted DHCPv4
DISCOVERY packets or DHCPv6 SOLICIT packets sent to `ff02::1:2` multicast
address. We don't need this in our production environment but adding that
support should be trivial though. PR are welcome!
# How does it work?
When operating in v4 mode `dhcplb` will relay relayed messages coming from other
relayers (in our production network those are rack switches), the response from
dhcp servers will be relayed back to the rack switches:
```
dhcp client <---> rsw relayer ---> dhcplb ---> dhcp server
^ |
| |
+-----------------------------+
```
In DHCPv6 mode `dhcplb` will operate normally, responses by the dhcp server
will traverse the load balancer.
# Requirements
`dhcplb` relies on the following libraries that you can get using the `go get`
command:
```
$ go get github.com/fsnotify/fsnotify
$ go get github.com/golang/glog
$ go get github.com/krolaw/dhcp4
$ go get github.com/facebookgo/ensure
```
# Installation
To install `dhcplb` in your `$GOPATH` simply run:
```
$ go get github.com/facebookincubator/dhcplb
```
This will fetch the source code and write it into
`$GOPATH/src/github.com/facebookincubator/dhcplb`, compile the binary and put
it in `$GOPATH/bin/dhcplb`.
# Cloning
If you wish to clone the repo you can do the following:
```
$ mkdir -p $GOPATH/src/github.com/facebookincubator
$ cd $_
$ git clone https://github.com/facebookincubator/dhcplb
$ go install github.com/facebookincubator/dhcplb
```
# Run unit tests
You can run tests with:
```
$ cd $GOPATH/src/github.com/facebookincubator/dhcplb/lib
$ go test
```
# Getting Started and extending `dhcplb`
`dhcplb` can be run out of the box after compilation.
To start immediately, you can run
`sudo dhcplb -config config.json -version 6`.
That will start the server in v6 mode using the default configuration.
Should you need to integrate `dhcplb` with your infrastructure please
see [Getting Started](docs/getting-started.md).
# TODOs / future improvements
- [ ] Add support for broadcast/multicast DISCOVERY/SOLICIT packets.
- [ ] Investigating using pool of goroutines rather than one per request, to improve memory efficiency.
- [ ] Improved LB algorithm (at the moment, hashing the mac address, it's good but not perfectly balanced).
- [ ] Increase test coverage.
PRs are welcome!
# Who wrote it?
`dhcplb` started in April 2016 during a 3 days hackathon in the Facebook
Dublin office, the hackathon project proved the feasibility of the tool.
In June we were joined by Vinnie Magro (@vmagro) for a 3 months internship in
which he worked with two production engineers on turning the hack into a
production ready system.
`dhcplb` has been deployed globally and currently balances all production DHCP
traffic efficiently across our KEA DHCP servers.
Hackathon project members:
* Angelo Failla ([@pallotron](https://github.com/pallotron)), Production Engineer
* Roman Gushchin ([@rgushchin](https://github.com/rgushchin)), Production Engineer
* Mateusz Kaczanowski ([@mkaczanowski](https://github.com/mkaczanowski)), Production Engineer
* Jake Bunce, Network Engineer
Internship project members:
* Vinnie Magro ([@vmagro](https://github.com/vmagro)), Production Engineer intern
* Angelo Failla (@pallotron), Intern mentor, Production Engineer
* Mateusz Kaczanowski (@mkaczanowski), Production Engineer
@@ -0,0 +1,26 @@
{
"v4": {
"version": 4,
"listen_addr": "0.0.0.0",
"port": 67,
"packet_buf_size": 1024,
"update_server_interval": 30,
"free_conn_timeout": 30,
"algorithm": "xid",
"host_sourcer": "file:hosts-v4.txt",
"packet_buf_pool_size": 1000,
"rc_ratio": 0
},
"v6": {
"version": 6,
"listen_addr": "::",
"port": 547,
"packet_buf_size": 1024,
"update_server_interval": 30,
"free_conn_timeout": 30,
"algorithm": "xid",
"host_sourcer": "file:hosts-v6.txt",
"packet_buf_pool_size": 1000,
"rc_ratio": 0
}
}
@@ -0,0 +1,45 @@
/**
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package main
import (
"encoding/json"
"github.com/facebookincubator/dhcplb/lib"
)
// DefaultConfigProvider holds configuration for the server.
type DefaultConfigProvider struct{}
// NewDefaultConfigProvider returns a new DefaultConfigProvider
func NewDefaultConfigProvider() *DefaultConfigProvider {
return &DefaultConfigProvider{}
}
// NewHostSourcer returns a dhcplb.DHCPServerSourcer interface.
// The default config loader is able to instantiate a FileSourcer by itself, so
// NewHostSourcer here will simply return (nil, nil).
// The FileSourcer implemments dhcplb.DHCPServerSourcer interface.
// If you are writing your own implementation of dhcplb you could write your
// custom sourcer implementation here.
// sourcerType
// The NewHostSourcer function is passed values from the host_sourcer json
// config option with the sourcerType being the part of the string before
// the : and args the remaining portion.
// ex: file:hosts-v4.txt,hosts-v4-rc.txt in the json config file will have
// sourcerType="file" and args="hosts-v4.txt,hosts-v4-rc.txt".
func (h DefaultConfigProvider) NewHostSourcer(sourcerType, args string, version int) (dhcplb.DHCPServerSourcer, error) {
return nil, nil
}
// ParseExtras is used to return extra config. Here we return nil because we
// don't need any extra configuration in the opensource version of dhcplb.
func (h DefaultConfigProvider) ParseExtras(data json.RawMessage) (interface{}, error) {
return nil, nil
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Oops, something went wrong.

0 comments on commit cd344d7

Please sign in to comment.