summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--table/destination.go56
-rw-r--r--table/path.go68
-rw-r--r--table/table.go66
-rw-r--r--table/table_manager.go2
4 files changed, 192 insertions, 0 deletions
diff --git a/table/destination.go b/table/destination.go
index 6734229a..edcda695 100644
--- a/table/destination.go
+++ b/table/destination.go
@@ -936,3 +936,59 @@ func (ipv6d *IPv6Destination) MarshalJSON() ([]byte, error) {
BestPathIdx: idx,
})
}
+
+type IPv4VPNDestination struct {
+ *DestinationDefault
+ //need structure
+}
+
+func NewIPv4VPNDestination(nlri bgp.AddrPrefixInterface) *IPv4VPNDestination {
+ ipv4VPNDestination := &IPv4VPNDestination{}
+ ipv4VPNDestination.DestinationDefault = NewDestinationDefault(nlri)
+ ipv4VPNDestination.DestinationDefault.ROUTE_FAMILY = bgp.RF_IPv4_VPN
+ //need Processing
+ return ipv4VPNDestination
+}
+
+func (ipv4vpnd *IPv4VPNDestination) String() string {
+
+ str := fmt.Sprintf("Destination NLRI: %s", ipv4vpnd.getPrefix().String())
+ return str
+}
+
+func (ipv4vpnd *IPv4VPNDestination) getPrefix() net.IP {
+ var ip net.IP
+ log.Debugf("type %s", reflect.TypeOf(ipv4vpnd.nlri))
+ switch p := ipv4vpnd.nlri.(type) {
+ case *bgp.IPv6AddrPrefix:
+ ip = p.IPAddrPrefix.IPAddrPrefixDefault.Prefix
+ case *bgp.WithdrawnRoute:
+ ip = p.IPAddrPrefix.IPAddrPrefixDefault.Prefix
+ }
+ return ip
+}
+
+func (ipv4vpnd *IPv4VPNDestination) MarshalJSON() ([]byte, error) {
+ prefix := ipv4vpnd.getNlri().(*bgp.LabelledVPNIPAddrPrefix).Prefix
+ idx := func() int {
+ for i, p := range ipv4vpnd.DestinationDefault.knownPathList {
+ if p == ipv4vpnd.DestinationDefault.getBestPath() {
+ return i
+ }
+ }
+ log.WithFields(log.Fields{
+ "Topic": "Table",
+ "Key": prefix.String(),
+ }).Panic("no best path")
+ return 0
+ }()
+ return json.Marshal(struct {
+ Prefix string
+ Paths []Path
+ BestPathIdx int
+ }{
+ Prefix: prefix.String(),
+ Paths: ipv4vpnd.knownPathList,
+ BestPathIdx: idx,
+ })
+}
diff --git a/table/path.go b/table/path.go
index 10374aa7..832a0ec6 100644
--- a/table/path.go
+++ b/table/path.go
@@ -224,6 +224,9 @@ func CreatePath(source *PeerInfo, nlri bgp.AddrPrefixInterface, attrs []bgp.Path
case bgp.RF_IPv6_UC:
log.Debugf("CreatePath RouteFamily : %s", bgp.RF_IPv6_UC.String())
path = NewIPv6Path(source, nlri, isWithdraw, attrs, false, now)
+ case bgp.RF_IPv4_VPN:
+ log.Debugf("CreatePath RouteFamily : %s", bgp.RF_IPv4_VPN.String())
+ path = NewIPv4VPNPath(source, nlri, isWithdraw, attrs, false, now)
}
return path
}
@@ -316,3 +319,68 @@ func (ipv6p *IPv6Path) MarshalJSON() ([]byte, error) {
Age: time.Now().Sub(ipv6p.PathDefault.timestamp).Seconds(),
})
}
+
+type IPv4VPNPath struct {
+ *PathDefault
+}
+
+func NewIPv4VPNPath(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, attrs []bgp.PathAttributeInterface, medSetByTargetNeighbor bool, now time.Time) *IPv4VPNPath {
+ ipv4VPNPath := &IPv4VPNPath{}
+ ipv4VPNPath.PathDefault = NewPathDefault(bgp.RF_IPv4_VPN, source, nlri, nil, isWithdraw, attrs, medSetByTargetNeighbor, now)
+ if !isWithdraw {
+ _, mpattr := ipv4VPNPath.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
+ ipv4VPNPath.nexthop = mpattr.(*bgp.PathAttributeMpReachNLRI).Nexthop
+ }
+ return ipv4VPNPath
+}
+
+func (ipv4vpnp *IPv4VPNPath) clone(isWithdraw bool) Path {
+ nlri := ipv4vpnp.nlri
+ if isWithdraw {
+ if ipv4vpnp.IsWithdraw() {
+ log.WithFields(log.Fields{
+ "Topic": "Table",
+ "Key": ipv4vpnp.getNlri().String(),
+ "Peer": ipv4vpnp.getSource().Address.String(),
+ }).Fatal("Withdraw path is not supposed to be cloned")
+ }
+ }
+ return CreatePath(ipv4vpnp.source, nlri, ipv4vpnp.pathAttrs, isWithdraw, ipv4vpnp.PathDefault.timestamp)
+}
+
+func (ipv4vpnp *IPv4VPNPath) setPathDefault(pd *PathDefault) {
+ ipv4vpnp.PathDefault = pd
+}
+
+func (ipv4vpnp *IPv4VPNPath) getPathDefault() *PathDefault {
+ return ipv4vpnp.PathDefault
+}
+
+func (ipv4vpnp *IPv4VPNPath) getPrefix() string {
+ addrPrefix := ipv4vpnp.nlri.(*bgp.LabelledVPNIPAddrPrefix)
+ return addrPrefix.IPAddrPrefixDefault.String()
+}
+
+// return IPv4VPNPath's string representation
+func (ipv4vpnp *IPv4VPNPath) String() string {
+ str := fmt.Sprintf("IPv4VPNPath Source: %v, ", ipv4vpnp.getSource())
+ str = str + fmt.Sprintf(" NLRI: %s, ", ipv4vpnp.getPrefix())
+ str = str + fmt.Sprintf(" nexthop: %s, ", ipv4vpnp.getNexthop().String())
+ str = str + fmt.Sprintf(" withdraw: %s, ", ipv4vpnp.IsWithdraw())
+ //str = str + fmt.Sprintf(" path attributes: %s, ", ipv4vpnp.getPathAttributeMap())
+ return str
+}
+
+func (ipv4vpnp *IPv4VPNPath) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Network string
+ Nexthop string
+ Attrs []bgp.PathAttributeInterface
+ Age float64
+ }{
+ Network: ipv4vpnp.getPrefix(),
+ Nexthop: ipv4vpnp.PathDefault.nexthop.String(),
+ Attrs: ipv4vpnp.PathDefault.getPathAttrs(),
+ Age: time.Now().Sub(ipv4vpnp.PathDefault.timestamp).Seconds(),
+ })
+}
diff --git a/table/table.go b/table/table.go
index 2bc328d8..c5ce287a 100644
--- a/table/table.go
+++ b/table/table.go
@@ -24,6 +24,8 @@ import (
"github.com/tchap/go-patricia/patricia"
"net"
"reflect"
+ "strconv"
+ "strings"
)
type Table interface {
@@ -315,3 +317,67 @@ func (ipv6t *IPv6Table) tableKey(nlri bgp.AddrPrefixInterface) string {
return addrPrefix.IPAddrPrefixDefault.String()
}
+
+type IPv4VPNTable struct {
+ *TableDefault
+ //need structure
+}
+
+func NewIPv4VPNTable(scope_id int) *IPv4VPNTable {
+ ipv4VPNTable := &IPv4VPNTable{}
+ ipv4VPNTable.TableDefault = NewTableDefault(scope_id)
+ ipv4VPNTable.TableDefault.ROUTE_FAMILY = bgp.RF_IPv4_VPN
+ //need Processing
+ return ipv4VPNTable
+}
+
+//Creates destination
+//Implements interface
+func (ipv4vpnt *IPv4VPNTable) createDest(nlri bgp.AddrPrefixInterface) Destination {
+ return Destination(NewIPv4VPNDestination(nlri))
+}
+
+//make tablekey
+//Implements interface
+func (ipv4vpnt *IPv4VPNTable) tableKey(nlri bgp.AddrPrefixInterface) string {
+
+ addrPrefix := nlri.(*bgp.LabelledVPNIPAddrPrefix)
+ return addrPrefix.IPAddrPrefixDefault.String()
+
+}
+
+func ParseLabbelledVpnPrefix(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])
+
+}
+
+func (ipv4vpnt *IPv4VPNTable) MarshalJSON() ([]byte, error) {
+
+ trie := patricia.NewTrie()
+ for key, dest := range ipv4vpnt.destinations {
+ trie.Insert(ParseLabbelledVpnPrefix(key), dest)
+ }
+
+ destList := make([]Destination, 0)
+ trie.Visit(func(prefix patricia.Prefix, item patricia.Item) error {
+ dest, _ := item.(Destination)
+ destList = append(destList, dest)
+ return nil
+ })
+
+ return json.Marshal(struct {
+ Destinations []Destination
+ }{
+ Destinations: destList,
+ })
+
+}
diff --git a/table/table_manager.go b/table/table_manager.go
index d0dd9f86..f2ff1ee6 100644
--- a/table/table_manager.go
+++ b/table/table_manager.go
@@ -138,6 +138,8 @@ func NewTableManager(owner string, rfList []bgp.RouteFamily) *TableManager {
t.Tables[bgp.RF_IPv4_UC] = NewIPv4Table(0)
case bgp.RF_IPv6_UC:
t.Tables[bgp.RF_IPv6_UC] = NewIPv6Table(0)
+ case bgp.RF_IPv4_VPN:
+ t.Tables[bgp.RF_IPv4_VPN] = NewIPv4VPNTable(0)
}
}
t.owner = owner