Beispiel #1
0
func NewDestination(nlri bgp.AddrPrefixInterface) *Destination {
	d := &Destination{
		routeFamily:   bgp.AfiSafiToRouteFamily(nlri.AFI(), nlri.SAFI()),
		nlri:          nlri,
		knownPathList: make([]*Path, 0),
		withdrawList:  make([]*Path, 0),
		newPathList:   make([]*Path, 0),
	}
	switch d.routeFamily {
	case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC:
		d.RadixKey = CidrToRadixkey(nlri.String())
	}
	return d
}
Beispiel #2
0
func NewPath(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, pattrs []bgp.PathAttributeInterface, timestamp time.Time, noImplicitWithdraw bool) *Path {
	if !isWithdraw && pattrs == nil {
		log.WithFields(log.Fields{
			"Topic": "Table",
			"Key":   nlri.String(),
			"Peer":  source.Address.String(),
		}).Error("Need to provide patattrs for the path that is not withdraw.")
		return nil
	}

	if nlri != nil && (nlri.SAFI() == bgp.SAFI_FLOW_SPEC_UNICAST || nlri.SAFI() == bgp.SAFI_FLOW_SPEC_VPN) {
		var coms FlowSpecComponents
		var f *bgp.FlowSpecNLRI
		switch nlri.(type) {
		case *bgp.FlowSpecIPv4Unicast:
			f = &nlri.(*bgp.FlowSpecIPv4Unicast).FlowSpecNLRI
		case *bgp.FlowSpecIPv4VPN:
			f = &nlri.(*bgp.FlowSpecIPv4VPN).FlowSpecNLRI
		case *bgp.FlowSpecIPv6Unicast:
			f = &nlri.(*bgp.FlowSpecIPv6Unicast).FlowSpecNLRI
		case *bgp.FlowSpecIPv6VPN:
			f = &nlri.(*bgp.FlowSpecIPv6VPN).FlowSpecNLRI
		}
		if f != nil {
			coms = f.Value
			sort.Sort(coms)
		}
	}

	return &Path{
		info: &originInfo{
			nlri:               nlri,
			source:             source,
			timestamp:          timestamp,
			noImplicitWithdraw: noImplicitWithdraw,
		},
		IsWithdraw: isWithdraw,
		pathAttrs:  pattrs,
		filtered:   make(map[string]PolicyDirection),
	}
}
Beispiel #3
0
func (t *Table) tableKey(nlri bgp.AddrPrefixInterface) string {
	return nlri.String()
}
Beispiel #4
0
//modrib receives route updates from BGP server and adds the endpoint
func (self *OfnetBgp) modRib(path *table.Path) error {
	var nlri bgp.AddrPrefixInterface
	var nextHop string
	var macAddrStr string
	var portNo uint32

	nlri = path.GetNlri()
	nextHop = path.GetNexthop().String()

	if nextHop == "0.0.0.0" {
		return nil
	}

	if nlri == nil {
		return fmt.Errorf("no nlri")
	}

	endpointIPNet, _ := netlink.ParseIPNet(nlri.String())
	log.Infof("Bgp Rib Received endpoint update for path %s", path.String())

	//check if bgp published a route local to the host
	epid := self.agent.getEndpointIdByIpVrf(endpointIPNet.IP.Mask(endpointIPNet.Mask), "default")

	//Check if the route is local
	if nextHop == self.routerIP {
		log.Debugf("This is a local route skipping endpoint create! ")
		return nil
	} else if ep := self.agent.getEndpointByID(epid); ep != nil {
		if ep.EndpointType != "external" {
			log.Debugf("Endpoint was learnt via internal protocol. skipping update! ")
			return nil
		}
	}

	nhEpid := self.agent.getEndpointIdByIpVrf(net.ParseIP(nextHop), "default")

	if ep := self.agent.getEndpointByID(nhEpid); ep == nil {
		//the nexthop is not the directly connected eBgp peer
		macAddrStr = ""
		portNo = 0
	} else {
		macAddrStr = ep.MacAddrStr
		portNo = ep.PortNo
	}

	ipmask := net.ParseIP("255.255.255.255").Mask(endpointIPNet.Mask)

	if path.IsWithdraw != true {
		epreg := &OfnetEndpoint{
			EndpointID:   epid,
			EndpointType: "external",
			IpAddr:       endpointIPNet.IP,
			IpMask:       ipmask,
			Vrf:          "default", // FIXME set VRF correctly
			MacAddrStr:   macAddrStr,
			Vlan:         1,
			OriginatorIp: self.agent.localIp,
			PortNo:       portNo,
			Timestamp:    time.Now(),
		}

		// Install the endpoint in datapath
		// First, add the endpoint to local routing table

		self.agent.endpointDb.Set(epreg.EndpointID, epreg)
		err := self.agent.datapath.AddEndpoint(epreg)
		if err != nil {
			log.Errorf("Error adding endpoint: {%+v}. Err: %v", epreg, err)
			return err
		}
	} else {
		log.Info("Received route withdraw from BGP for ", endpointIPNet)
		endpoint := self.agent.getEndpointByIpVrf(endpointIPNet.IP, "default")
		if endpoint != nil {
			self.agent.datapath.RemoveEndpoint(endpoint)
			self.agent.endpointDb.Remove(endpoint.EndpointID)
		}
	}
	return nil
}
Beispiel #5
0
//modrib receives route updates from BGP server and adds the endpoint
func (self *OfnetBgp) modRib(path *api.Path) error {
	var nlri bgp.AddrPrefixInterface
	var nextHop string
	var macAddrStr string
	var portNo uint32
	if len(path.Nlri) > 0 {
		nlri = &bgp.IPAddrPrefix{}
		err := nlri.DecodeFromBytes(path.Nlri)
		if err != nil {
			return err
		}
	}

	for _, attr := range path.Pattrs {
		p, err := bgp.GetPathAttribute(attr)
		if err != nil {
			return err
		}

		err = p.DecodeFromBytes(attr)
		if err != nil {
			return err
		}

		if p.GetType() == bgp.BGP_ATTR_TYPE_NEXT_HOP {
			nextHop = p.(*bgp.PathAttributeNextHop).Value.String()
			break
		}
	}
	if nextHop == "0.0.0.0" {
		return nil
	}

	if nlri == nil {
		return fmt.Errorf("no nlri")
	}

	endpointIPNet, _ := netlink.ParseIPNet(nlri.String())
	log.Infof("Bgp Rib Received endpoint update for %v , with nexthop %v",
		endpointIPNet, nextHop)
	if endpointIPNet == nil {
		return nil
	}
	//check if bgp published a route local to the host
	epid := self.agent.getEndpointIdByIpVrf(endpointIPNet.IP.Mask(endpointIPNet.Mask), "default")

	//Check if the route is local
	if nextHop == self.routerIP {
		log.Info("This is a local route skipping endpoint create! ")
		return nil
	} else if self.agent.endpointDb[epid] != nil {
		if self.agent.endpointDb[epid].EndpointType != "external" {
			log.Info("Endpoint was learnt via internal protocol. skipping update! ")
			return nil
		}
	}
	nhEpid := self.agent.getEndpointIdByIpVrf(net.ParseIP(nextHop), "default")
	if self.agent.endpointDb[nhEpid] == nil {
		//the nexthop is not the directly connected eBgp peer
		macAddrStr = ""
		portNo = 0
	} else {
		macAddrStr = self.agent.endpointDb[nhEpid].MacAddrStr
		portNo = self.agent.endpointDb[nhEpid].PortNo
	}

	ipmask := net.ParseIP("255.255.255.255").Mask(endpointIPNet.Mask)

	if path.IsWithdraw != true {
		epreg := &OfnetEndpoint{
			EndpointID:   epid,
			EndpointType: "external",
			IpAddr:       endpointIPNet.IP,
			IpMask:       ipmask,
			Vrf:          "default", // FIXME set VRF correctly
			MacAddrStr:   macAddrStr,
			Vlan:         1,
			OriginatorIp: self.agent.localIp,
			PortNo:       portNo,
			Timestamp:    time.Now(),
		}

		// Install the endpoint in datapath
		// First, add the endpoint to local routing table
		self.agent.endpointDb[epreg.EndpointID] = epreg
		err := self.agent.datapath.AddEndpoint(epreg)
		if err != nil {
			log.Errorf("Error adding endpoint: {%+v}. Err: %v", epreg, err)
			return err
		}
	} else {
		log.Info("Received route withdraw from BGP for ", endpointIPNet)
		endpoint := self.agent.getEndpointByIpVrf(endpointIPNet.IP, "default")
		if endpoint != nil {
			self.agent.datapath.RemoveEndpoint(endpoint)
			delete(self.agent.endpointDb, endpoint.EndpointID)
		}
	}
	return nil
}