Skip to content
This repository has been archived by the owner on Feb 2, 2024. It is now read-only.

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
Signed-off-by: ISHIDA Wataru <[email protected]>
  • Loading branch information
ISHIDA Wataru committed Feb 27, 2017
1 parent c851917 commit df33924
Show file tree
Hide file tree
Showing 22 changed files with 1,768 additions and 1,627 deletions.
7 changes: 7 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,12 @@ matrix:
services:
- docker
script: test/travis_script.sh
- go: 1.7
sudo: required
env:
- TEST=test/netlink/iptables_test.py
services:
- docker
script: test/travis_script.sh

go_import_path: github.com/osrg/goplane
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ FROM osrg/gobgp

MAINTAINER ISHIDA Wataru <[email protected]>

RUN apt-get install -qy iptables
ENV GO15VENDOREXPERIMENT 1
RUN curl https://glide.sh/get | sh
ADD . $GOPATH/src/github.com/osrg/goplane/
Expand Down
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type Iptables struct {
}

type Config struct {
RouterID string `mapstructure:"router-id"`
Dataplane Dataplane `mapstructure:"dataplane"`
Iptables Iptables `mapstructure:"iptables"`
BGP bgpconfig.BgpConfigSet `mapstructure:"bgp"`
Expand Down
127 changes: 127 additions & 0 deletions dataplane.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Copyright (C) 2017 Nippon Telegraph and Telephone Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"fmt"
"net"
"sync"

log "github.com/Sirupsen/logrus"
"github.com/osrg/goplane/config"
proto "github.com/osrg/goplane/protocol"
)

type Dataplane struct {
routerID net.IP
protos map[proto.ProtocolType]proto.Protocol
routeEventCh chan []proto.EntryEvent
m sync.RWMutex
}

func NewDataplane() *Dataplane {
d := &Dataplane{
protos: make(map[proto.ProtocolType]proto.Protocol),
routeEventCh: make(chan []proto.EntryEvent, 0),
}
go func() {
log.Fatal(d.serve())
}()
return d
}

func (d *Dataplane) serve() error {
for {
for _, ev := range <-d.routeEventCh {
log.Info("ev:", ev)
d.m.RLock()
for _, proto := range d.protos {
if ev.From == proto.Type() || ev.Entry.Match() == nil {
continue
}
var err error
if ev.IsDel {
err = proto.DeleteEntry(ev.Entry)
} else {
err = proto.AddEntry(ev.Entry)
}
if err != nil {
log.Errorf("err: %v", err)
}
}
d.m.RUnlock()
}
}
return nil
}

func (d *Dataplane) SetRouterID(id net.IP) error {
d.m.RLock()
defer d.m.RUnlock()
for _, proto := range d.protos {
if err := proto.SetRouterID(id); err != nil {
return err
}
}
return nil
}

func (d *Dataplane) AddProtocol(p proto.Protocol) error {
d.m.Lock()
defer d.m.Unlock()
if _, y := d.protos[p.Type()]; y {
return fmt.Errorf("protocol %d already exists", p.Type())
}
d.protos[p.Type()] = p
w, err := p.WatchEntry()
if err != nil {
return err
}
if w != nil {
go func() {
for {
rs, err := w.Recv()
if err != nil {
log.Fatalf("failed recv routes: %s", err)
}
d.routeEventCh <- rs
}
}()
}
return nil
}

func (d *Dataplane) AddVirtualNetwork(c config.VirtualNetwork) error {
d.m.RLock()
defer d.m.RUnlock()
for _, proto := range d.protos {
if err := proto.AddVirtualNetwork(d.routerID.String(), c); err != nil {
return err
}
}
return nil
}

func (d *Dataplane) DeleteVirtualNetwork(c config.VirtualNetwork) error {
d.m.RLock()
defer d.m.RUnlock()
for _, proto := range d.protos {
if err := proto.DeleteVirtualNetwork(c); err != nil {
return err
}
}
return nil
}
139 changes: 23 additions & 116 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,23 @@ package main
import (
"io/ioutil"
"log/syslog"
"net"
"os"
"os/signal"
"runtime"
"strings"
"syscall"
"time"

log "github.com/Sirupsen/logrus"
"github.com/Sirupsen/logrus/hooks/syslog"
"github.com/jessevdk/go-flags"
"github.com/osrg/goplane/config"
"github.com/osrg/goplane/iptables"
"github.com/osrg/goplane/netlink"
p "github.com/osrg/goplane/protocol"
"github.com/osrg/goplane/protocol/iptables"
"github.com/osrg/goplane/protocol/netlink"

bgpapi "github.com/osrg/gobgp/api"
bgpconfig "github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
bgpserver "github.com/osrg/gobgp/server"
)

type Dataplaner interface {
Expand Down Expand Up @@ -157,127 +157,44 @@ func main() {
go config.ReadConfigfileServe(opts.ConfigFile, opts.ConfigType, configCh, bgpConfigCh, reloadCh)
reloadCh <- true

var bgpServer *bgpserver.BgpServer
if !opts.Remote {
bgpServer = bgpserver.NewBgpServer()
go bgpServer.Serve()
grpcServer := bgpapi.NewGrpcServer(bgpServer, opts.GrpcHost)
go func() {
if err := grpcServer.Serve(); err != nil {
log.Fatalf("failed to listen grpc port: %s", err)
}
}()
}
bgpProtocol := p.NewGoBGPProtocol()
dataplane := NewDataplane()
dataplane.AddProtocol(bgpProtocol)

var dataplane Dataplaner
var d *config.Dataplane
var c *bgpconfig.BgpConfigSet
var fsAgent *iptables.FlowspecAgent
for {
select {
case newConfig := <-bgpConfigCh:
if opts.Remote {
log.Warn("running in BGP remote mode. you can't configure BGP daemon via configuration file now")
continue
}

var added, deleted, updated []bgpconfig.Neighbor
var updatePolicy bool

if c == nil {
c = newConfig
if err := bgpServer.Start(&newConfig.Global); err != nil {
log.Fatalf("failed to set global config: %s", err)
}
if newConfig.Zebra.Config.Enabled {
if err := bgpServer.StartZebraClient(&newConfig.Zebra.Config); err != nil {
log.Fatalf("failed to set zebra config: %s", err)
}
}
if len(newConfig.Collector.Config.Url) > 0 {
if err := bgpServer.StartCollector(&newConfig.Collector.Config); err != nil {
log.Fatalf("failed to set collector config: %s", err)
}
}
for _, c := range newConfig.RpkiServers {
if err := bgpServer.AddRpki(&c.Config); err != nil {
log.Fatalf("failed to set rpki config: %s", err)
}
}
for _, c := range newConfig.BmpServers {
if err := bgpServer.AddBmp(&c.Config); err != nil {
log.Fatalf("failed to set bmp config: %s", err)
}
}
for _, c := range newConfig.MrtDump {
if len(c.Config.FileName) == 0 {
continue
}
if err := bgpServer.EnableMrt(&c.Config); err != nil {
log.Fatalf("failed to set mrt config: %s", err)
}
}
p := bgpconfig.ConfigSetToRoutingPolicy(newConfig)
if err := bgpServer.UpdatePolicy(*p); err != nil {
log.Fatalf("failed to set routing policy: %s", err)
}

added = newConfig.Neighbors
if opts.GracefulRestart {
for i, n := range added {
if n.GracefulRestart.Config.Enabled {
added[i].GracefulRestart.State.LocalRestarting = true
}
}
}

} else {
added, deleted, updated, updatePolicy = bgpconfig.UpdateConfig(c, newConfig)
if updatePolicy {
log.Info("Policy config is updated")
p := bgpconfig.ConfigSetToRoutingPolicy(newConfig)
bgpServer.UpdatePolicy(*p)
}
c = newConfig
if err := bgpProtocol.UpdateConfig(newConfig); err != nil {
log.Fatalf("failed to update BGP config: %s", err)
}

for i, p := range added {
log.Infof("Peer %v is added", p.Config.NeighborAddress)
bgpServer.AddNeighbor(&added[i])
}
for i, p := range deleted {
log.Infof("Peer %v is deleted", p.Config.NeighborAddress)
bgpServer.DeleteNeighbor(&deleted[i])
}
for i, p := range updated {
log.Infof("Peer %v is updated", p.Config.NeighborAddress)
u, _ := bgpServer.UpdateNeighbor(&updated[i])
updatePolicy = updatePolicy || u
}

if updatePolicy {
bgpServer.SoftResetIn("", bgp.RouteFamily(0))
}

case newConfig := <-configCh:
if dataplane == nil {
if d == nil {
switch newConfig.Dataplane.Type {
case "netlink":
log.Debug("new dataplane: netlink")
dataplane = netlink.NewDataplane(newConfig, opts.GrpcHost)
go func() {
err := dataplane.Serve()
if err != nil {
log.Errorf("dataplane finished with err: %s", err)
}
}()
dataplane.AddProtocol(netlink.NewNetlinkProtocol())
default:
log.Errorf("Invalid dataplane type(%s). dataplane engine can't be started", newConfig.Dataplane.Type)
}

time.Sleep(time.Millisecond)

if err := dataplane.SetRouterID(net.ParseIP(newConfig.RouterID)); err != nil {
log.Fatal(err)
}

if newConfig.Iptables.Enabled {
dataplane.AddProtocol(iptables.NewIPTablesProtocol(newConfig.Iptables))
}
}
d = &newConfig.Dataplane

as, ds := config.UpdateConfig(d, newConfig.Dataplane)
d = &newConfig.Dataplane

for _, v := range as {
log.Infof("VirtualNetwork %s is added", v.RD)
Expand All @@ -288,16 +205,6 @@ func main() {
dataplane.DeleteVirtualNetwork(v)
}

if fsAgent == nil && newConfig.Iptables.Enabled {
fsAgent = iptables.NewFlowspecAgent(opts.GrpcHost, newConfig.Iptables)
go func() {
err := fsAgent.Serve()
if err != nil {
log.Errorf("flowspec agent finished with err: %s", err)
}
}()
}

case sig := <-sigCh:
switch sig {
case syscall.SIGHUP:
Expand Down
Loading

0 comments on commit df33924

Please sign in to comment.