summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYuji Oshima <yuji.oshima0x3fd@gmail.com>2015-03-21 08:08:43 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-03-21 08:08:43 +0900
commit28feabe1ef3961e05e0e109551021f0bc8902abe (patch)
tree5b055cd546c0561e4fd2ac1cdb70a07fc17d6f3e
parent84f6e0b04cc48289d342d0b904c43ab19ba2a427 (diff)
table: add EVPN route family support
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--table/destination.go13
-rw-r--r--table/message.go2
-rw-r--r--table/path.go69
-rw-r--r--table/table.go40
-rw-r--r--table/table_manager.go3
5 files changed, 126 insertions, 1 deletions
diff --git a/table/destination.go b/table/destination.go
index edcda695..f805d5e3 100644
--- a/table/destination.go
+++ b/table/destination.go
@@ -992,3 +992,16 @@ func (ipv4vpnd *IPv4VPNDestination) MarshalJSON() ([]byte, error) {
BestPathIdx: idx,
})
}
+
+type EVPNDestination struct {
+ *DestinationDefault
+ //need structure
+}
+
+func NewEVPNDestination(nlri bgp.AddrPrefixInterface) *EVPNDestination {
+ EVPNDestination := &EVPNDestination{}
+ EVPNDestination.DestinationDefault = NewDestinationDefault(nlri)
+ EVPNDestination.DestinationDefault.ROUTE_FAMILY = bgp.RF_EVPN
+ //need Processing
+ return EVPNDestination
+}
diff --git a/table/message.go b/table/message.go
index b19bcec2..10bf0afd 100644
--- a/table/message.go
+++ b/table/message.go
@@ -161,7 +161,7 @@ func createUpdateMsgFromPath(path Path, msg *bgp.BGPMessage) *bgp.BGPMessage {
return bgp.NewBGPUpdateMessage([]bgp.WithdrawnRoute{}, pathAttrs, []bgp.NLRInfo{*nlri})
}
}
- } else if rf == bgp.RF_IPv6_UC {
+ } else if rf == bgp.RF_IPv6_UC || rf == bgp.RF_EVPN {
if path.IsWithdraw() {
if msg != nil {
idx, _ := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
diff --git a/table/path.go b/table/path.go
index 5ff4ca2a..73475e98 100644
--- a/table/path.go
+++ b/table/path.go
@@ -318,6 +318,9 @@ func CreatePath(source *PeerInfo, nlri bgp.AddrPrefixInterface, attrs []bgp.Path
case bgp.RF_IPv4_VPN:
log.Debugf("CreatePath RouteFamily : %s", bgp.RF_IPv4_VPN.String())
path = NewIPv4VPNPath(source, nlri, isWithdraw, attrs, false, now)
+ case bgp.RF_EVPN:
+ log.Debugf("CreatePath RouteFamily : %s", bgp.RF_EVPN.String())
+ path = NewEVPNPath(source, nlri, isWithdraw, attrs, false, now)
}
return path
}
@@ -466,3 +469,69 @@ func (ipv4vpnp *IPv4VPNPath) MarshalJSON() ([]byte, error) {
Age: time.Now().Sub(ipv4vpnp.PathDefault.timestamp).Seconds(),
})
}
+
+type EVPNPath struct {
+ *PathDefault
+}
+
+func NewEVPNPath(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, attrs []bgp.PathAttributeInterface, medSetByTargetNeighbor bool, now time.Time) *EVPNPath {
+ EVPNPath := &EVPNPath{}
+ EVPNPath.PathDefault = NewPathDefault(bgp.RF_EVPN, source, nlri, nil, isWithdraw, attrs, medSetByTargetNeighbor, now)
+ if !isWithdraw {
+ _, mpattr := EVPNPath.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
+ EVPNPath.nexthop = mpattr.(*bgp.PathAttributeMpReachNLRI).Nexthop
+ }
+
+ return EVPNPath
+}
+
+func (evpnp *EVPNPath) clone(isWithdraw bool) Path {
+ nlri := evpnp.nlri
+ if isWithdraw {
+ if evpnp.IsWithdraw() {
+ log.WithFields(log.Fields{
+ "Topic": "Table",
+ "Key": evpnp.getNlri().String(),
+ "Peer": evpnp.getSource().Address.String(),
+ }).Fatal("Withdraw path is not supposed to be cloned")
+ }
+ }
+ return CreatePath(evpnp.source, nlri, evpnp.pathAttrs, isWithdraw, evpnp.PathDefault.timestamp)
+}
+
+func (evpnp *EVPNPath) setPathDefault(pd *PathDefault) {
+ evpnp.PathDefault = pd
+}
+
+func (evpnp *EVPNPath) getPathDefault() *PathDefault {
+ return evpnp.PathDefault
+}
+
+func (evpnp *EVPNPath) getPrefix() string {
+ addrPrefix := evpnp.nlri.(*bgp.EVPNNLRI)
+ return addrPrefix.String()
+}
+
+// return EVPNPath's string representation
+func (evpnp *EVPNPath) String() string {
+ str := fmt.Sprintf("EVPNPath Source: %v, ", evpnp.getSource())
+ str = str + fmt.Sprintf(" NLRI: %s, ", evpnp.getPrefix())
+ str = str + fmt.Sprintf(" nexthop: %s, ", evpnp.GetNexthop().String())
+ str = str + fmt.Sprintf(" withdraw: %s, ", evpnp.IsWithdraw())
+ //str = str + fmt.Sprintf(" path attributes: %s, ", evpnp.getPathAttributeMap())
+ return str
+}
+
+func (evpnp *EVPNPath) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Network string
+ Nexthop string
+ Attrs []bgp.PathAttributeInterface
+ Age float64
+ }{
+ Network: evpnp.getPrefix(),
+ Nexthop: evpnp.PathDefault.nexthop.String(),
+ Attrs: evpnp.PathDefault.getPathAttrs(),
+ Age: time.Now().Sub(evpnp.PathDefault.timestamp).Seconds(),
+ })
+}
diff --git a/table/table.go b/table/table.go
index c5ce287a..47e42fbb 100644
--- a/table/table.go
+++ b/table/table.go
@@ -381,3 +381,43 @@ func (ipv4vpnt *IPv4VPNTable) MarshalJSON() ([]byte, error) {
})
}
+
+type EVPNTable struct {
+ *TableDefault
+ //need structure
+}
+
+func NewEVPNTable(scope_id int) *EVPNTable {
+ EVPNTable := &EVPNTable{}
+ EVPNTable.TableDefault = NewTableDefault(scope_id)
+ EVPNTable.TableDefault.ROUTE_FAMILY = bgp.RF_EVPN
+ //need Processing
+ return EVPNTable
+}
+
+//Creates destination
+//Implements interface
+func (ipv4vpnt *EVPNTable) createDest(nlri bgp.AddrPrefixInterface) Destination {
+ return Destination(NewEVPNDestination(nlri))
+}
+
+//make tablekey
+//Implements interface
+func (ipv4vpnt *EVPNTable) tableKey(nlri bgp.AddrPrefixInterface) string {
+
+ addrPrefix := nlri.(*bgp.EVPNNLRI)
+ return addrPrefix.String()
+}
+
+func ParseEVPNPrefix(key string) patricia.Prefix {
+ vpnaddrprefix := strings.Split(key, "/")
+ length, _ := strconv.ParseInt(vpnaddrprefix[1], 10, 0)
+ _, n, _ := net.ParseCIDR(vpnaddrprefix[0] + "/" + strconv.FormatInt((int64(length)-88), 10))
+
+ var buffer bytes.Buffer
+ for i := 0; i < len(n.IP); i++ {
+ buffer.WriteString(fmt.Sprintf("%08b", n.IP[i]))
+ }
+ ones, _ := n.Mask.Size()
+ return patricia.Prefix(buffer.String()[:ones])
+}
diff --git a/table/table_manager.go b/table/table_manager.go
index 23c233b1..7722ce19 100644
--- a/table/table_manager.go
+++ b/table/table_manager.go
@@ -140,6 +140,9 @@ func NewTableManager(owner string, rfList []bgp.RouteFamily) *TableManager {
t.Tables[bgp.RF_IPv6_UC] = NewIPv6Table(0)
case bgp.RF_IPv4_VPN:
t.Tables[bgp.RF_IPv4_VPN] = NewIPv4VPNTable(0)
+ case bgp.RF_EVPN:
+ t.Tables[bgp.RF_EVPN] = NewEVPNTable(0)
+
}
}
t.owner = owner