diff --git a/config/peer.go b/config/peer.go
index 245c1aa2c940a3e878c296748b3c79c62882d479..418d8e00488ddbdde0b6c2cb86b6bcd3e1153644 100644
--- a/config/peer.go
+++ b/config/peer.go
@@ -5,6 +5,7 @@ import (
 	"time"
 
 	"github.com/bio-routing/bio-rd/routingtable"
+	"github.com/bio-routing/bio-rd/routingtable/filter"
 )
 
 type Peer struct {
@@ -20,4 +21,6 @@ type Peer struct {
 	RouterID          uint32
 	AddPathSend       routingtable.ClientOptions
 	AddPathRecv       bool
+	ImportFilter      *filter.Filter
+	ExportFilter      *filter.Filter
 }
diff --git a/main.go b/main.go
index 49d19c0f0f76019ae6f522b5f82e0262b5ec99a9..f74f4a0d82aa55412b840ebb83fdecee76733c39 100644
--- a/main.go
+++ b/main.go
@@ -11,6 +11,7 @@ import (
 	"github.com/bio-routing/bio-rd/config"
 	"github.com/bio-routing/bio-rd/protocols/bgp/server"
 	"github.com/bio-routing/bio-rd/routingtable"
+	"github.com/bio-routing/bio-rd/routingtable/filter"
 	"github.com/bio-routing/bio-rd/routingtable/locRIB"
 )
 
@@ -45,6 +46,8 @@ func main() {
 		AddPathSend: routingtable.ClientOptions{
 			MaxPaths: 10,
 		},
+		ExportFilter: filter.NewAcceptAllFilter(),
+		ImportFilter: filter.NewDrainFilter(),
 	}, rib)
 
 	//time.Sleep(time.Second * 15)
@@ -63,7 +66,9 @@ func main() {
 		AddPathSend: routingtable.ClientOptions{
 			MaxPaths: 10,
 		},
-		AddPathRecv: true,
+		AddPathRecv:  true,
+		ImportFilter: filter.NewDrainFilter(),
+		ExportFilter: filter.NewAcceptAllFilter(),
 	}, rib)
 
 	go func() {
diff --git a/protocols/bgp/server/fsm_established.go b/protocols/bgp/server/fsm_established.go
index 87ef4ba1f935e8ae8068c2a63ce0789eb7db0bf7..e54e64533fea03560334370a7d47b7774934d98a 100644
--- a/protocols/bgp/server/fsm_established.go
+++ b/protocols/bgp/server/fsm_established.go
@@ -53,7 +53,9 @@ func (s establishedState) run() (state, string) {
 
 func (s *establishedState) init() {
 	s.fsm.adjRIBIn = adjRIBIn.New()
-	s.fsm.adjRIBIn.Register(s.fsm.rib)
+
+	s.fsm.peer.importFilter.Register(s.fsm.rib)
+	s.fsm.adjRIBIn.Register(s.fsm.peer.importFilter)
 
 	n := &routingtable.Neighbor{
 		Type:    route.BGPPathType,
@@ -71,7 +73,8 @@ func (s *establishedState) init() {
 	}
 
 	s.fsm.adjRIBOut.Register(s.fsm.updateSender)
-	s.fsm.rib.RegisterWithOptions(s.fsm.adjRIBOut, clientOptions)
+	s.fsm.peer.exportFilter.Register(s.fsm.adjRIBOut)
+	s.fsm.rib.RegisterWithOptions(s.fsm.peer.exportFilter, clientOptions)
 
 	s.fsm.ribsInitialized = true
 }
diff --git a/protocols/bgp/server/peer.go b/protocols/bgp/server/peer.go
index 26f183ce7b7572f71a6edc6982122eccf88fccf2..a0e4c623b5d4d30bdb877311c879b7c568332859 100644
--- a/protocols/bgp/server/peer.go
+++ b/protocols/bgp/server/peer.go
@@ -96,6 +96,8 @@ func NewPeer(c config.Peer, rib routingtable.RouteTableClient, server *BGPServer
 		keepaliveTime:     c.KeepAlive,
 		holdTime:          c.HoldTime,
 		optOpenParams:     make([]packet.OptParam, 0),
+		importFilter:      filterOrDefault(c.ImportFilter),
+		exportFilter:      filterOrDefault(c.ExportFilter),
 	}
 	p.fsms = append(p.fsms, NewActiveFSM2(p))
 
@@ -130,6 +132,14 @@ func NewPeer(c config.Peer, rib routingtable.RouteTableClient, server *BGPServer
 	return p, nil
 }
 
+func filterOrDefault(f *filter.Filter) *filter.Filter {
+	if f != nil {
+		return f
+	}
+
+	return filter.NewDrainFilter()
+}
+
 // GetAddr returns the IP address of the peer
 func (p *Peer) GetAddr() net.IP {
 	return p.addr
diff --git a/routingtable/filter/helper.go b/routingtable/filter/helper.go
new file mode 100644
index 0000000000000000000000000000000000000000..17a7d73789d5be569bec1725592a35f1b3841386
--- /dev/null
+++ b/routingtable/filter/helper.go
@@ -0,0 +1,29 @@
+package filter
+
+import (
+	"github.com/bio-routing/bio-rd/routingtable/filter/actions"
+)
+
+// NewAcceptAllFilter returns a filter accepting any paths/prefixes
+func NewAcceptAllFilter() *Filter {
+	return NewFilter(
+		[]*Term{
+			NewTerm(
+				[]*TermCondition{},
+				[]FilterAction{
+					&actions.AcceptAction{},
+				}),
+		})
+}
+
+// NewDrainFilter returns a filter rejecting any paths/prefixes
+func NewDrainFilter() *Filter {
+	return NewFilter(
+		[]*Term{
+			NewTerm(
+				[]*TermCondition{},
+				[]FilterAction{
+					&actions.RejectAction{},
+				}),
+		})
+}
diff --git a/routingtable/filter/helper_test.go b/routingtable/filter/helper_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..a0370e7677aa303dcc2efc5d0242f2f287222d9a
--- /dev/null
+++ b/routingtable/filter/helper_test.go
@@ -0,0 +1,34 @@
+package filter
+
+import (
+	"testing"
+
+	"github.com/bio-routing/bio-rd/net"
+	"github.com/bio-routing/bio-rd/route"
+)
+
+func TestNewAcceptAllFilter(t *testing.T) {
+	f := NewAcceptAllFilter()
+
+	m := &clientMock{}
+	f.Register(m)
+
+	f.AddPath(net.NewPfx(0, 0), &route.Path{})
+
+	if !m.addPathCalled {
+		t.Fatalf("expected accepted, but was filtered")
+	}
+}
+
+func TestNewDrainFilter(t *testing.T) {
+	f := NewDrainFilter()
+
+	m := &clientMock{}
+	f.Register(m)
+
+	f.AddPath(net.NewPfx(0, 0), &route.Path{})
+
+	if m.addPathCalled {
+		t.Fatalf("expected filtered, but was accepted")
+	}
+}
diff --git a/routingtable/filter/term.go b/routingtable/filter/term.go
index 0d546be8bc7ceaf07e12a85453ed5cce741ea3cd..d644acba4a977e67e757fc5c7f71863531427e12 100644
--- a/routingtable/filter/term.go
+++ b/routingtable/filter/term.go
@@ -39,7 +39,7 @@ func (t *Term) Process(p net.Prefix, pa *route.Path) (modPath *route.Path, rejec
 		}
 	}
 
-	return orig, true
+	return orig, false
 }
 
 func (t *Term) processActions(p net.Prefix, pa *route.Path) (modPath *route.Path, reject bool) {
diff --git a/routingtable/filter/term_condition.go b/routingtable/filter/term_condition.go
index fe19e461701dc1a453a3ddee17a38547d08936a6..9839ebe65397cb13af7bf3943761a91c108409c5 100644
--- a/routingtable/filter/term_condition.go
+++ b/routingtable/filter/term_condition.go
@@ -19,6 +19,18 @@ func NewTermCondition(prefixLists []*PrefixList, routeFilters []*RouteFilter) *T
 	}
 }
 
+func NewTermConditionWithRouteFilters(filters ...*RouteFilter) *TermCondition {
+	return &TermCondition{
+		routeFilters: filters,
+	}
+}
+
+func NewTermConditionWithPrefixLists(filters ...*PrefixList) *TermCondition {
+	return &TermCondition{
+		prefixLists: filters,
+	}
+}
+
 func (f *TermCondition) Matches(p net.Prefix, pa *route.Path) bool {
 	return f.matchesPrefixListFilters(p) &&
 		f.machtchesRouteFilters(p) &&
diff --git a/routingtable/filter/term_test.go b/routingtable/filter/term_test.go
index 967480e76cdaa8a81f7594651b83fa8405fe02f9..d3abef87b52d2679084827283744e9b73599b433 100644
--- a/routingtable/filter/term_test.go
+++ b/routingtable/filter/term_test.go
@@ -45,11 +45,8 @@ func TestProcess(t *testing.T) {
 			prefix: net.NewPfx(strAddr("100.64.0.1"), 8),
 			path:   &route.Path{},
 			from: []*TermCondition{
-				{
-					prefixLists: []*PrefixList{
-						NewPrefixList(net.NewPfx(strAddr("100.64.0.1"), 8)),
-					},
-				},
+				NewTermConditionWithPrefixLists(
+					NewPrefixList(net.NewPfx(strAddr("100.64.0.1"), 8))),
 			},
 			then: []FilterAction{
 				&actions.AcceptAction{},
@@ -62,16 +59,13 @@ func TestProcess(t *testing.T) {
 			prefix: net.NewPfx(strAddr("100.64.0.1"), 8),
 			path:   &route.Path{},
 			from: []*TermCondition{
-				{
-					prefixLists: []*PrefixList{
-						NewPrefixList(net.NewPfx(0, 32)),
-					},
-				},
+				NewTermConditionWithPrefixLists(
+					NewPrefixList(net.NewPfx(0, 32))),
 			},
 			then: []FilterAction{
 				&actions.AcceptAction{},
 			},
-			expectReject:   true,
+			expectReject:   false,
 			expectModified: false,
 		},
 		{
@@ -79,11 +73,8 @@ func TestProcess(t *testing.T) {
 			prefix: net.NewPfx(strAddr("100.64.0.1"), 8),
 			path:   &route.Path{},
 			from: []*TermCondition{
-				{
-					prefixLists: []*PrefixList{
-						NewPrefixList(net.NewPfx(strAddr("100.64.0.1"), 8)),
-					},
-				},
+				NewTermConditionWithPrefixLists(
+					NewPrefixList(net.NewPfx(strAddr("100.64.0.1"), 8))),
 			},
 			then: []FilterAction{
 				&mockAction{},
@@ -96,11 +87,8 @@ func TestProcess(t *testing.T) {
 			prefix: net.NewPfx(strAddr("100.64.0.1"), 8),
 			path:   &route.Path{},
 			from: []*TermCondition{
-				{
-					prefixLists: []*PrefixList{
-						NewPrefixList(net.NewPfx(strAddr("100.64.0.1"), 8)),
-					},
-				},
+				NewTermConditionWithRouteFilters(
+					NewRouteFilter(net.NewPfx(strAddr("100.64.0.1"), 8), Exact())),
 			},
 			then: []FilterAction{
 				&mockAction{},