func newIPRouteMessage(path *table.Path) *zebra.Message {
	l := strings.SplitN(path.GetNlri().String(), "/", 2)
	var command zebra.API_TYPE
	var prefix net.IP
	nexthops := []net.IP{}
	switch path.GetRouteFamily() {
	case bgp.RF_IPv4_UC:
		if path.IsWithdraw == true {
			command = zebra.IPV4_ROUTE_DELETE
		} else {
			command = zebra.IPV4_ROUTE_ADD
		}
		prefix = net.ParseIP(l[0]).To4()
		nexthops = append(nexthops, path.GetNexthop().To4())
	case bgp.RF_IPv6_UC:
		if path.IsWithdraw == true {
			command = zebra.IPV6_ROUTE_DELETE
		} else {
			command = zebra.IPV6_ROUTE_ADD
		}
		prefix = net.ParseIP(l[0]).To16()
		nexthops = append(nexthops, path.GetNexthop().To16())
	default:
		return nil
	}

	flags := uint8(zebra.MESSAGE_NEXTHOP)
	plen, _ := strconv.Atoi(l[1])
	med, err := path.GetMed()
	if err == nil {
		flags |= zebra.MESSAGE_METRIC
	}
	return &zebra.Message{
		Header: zebra.Header{
			Len:     zebra.HEADER_SIZE,
			Marker:  zebra.HEADER_MARKER,
			Version: zebra.VERSION,
			Command: command,
		},
		Body: &zebra.IPRouteBody{
			Type:         zebra.ROUTE_BGP,
			SAFI:         zebra.SAFI_UNICAST,
			Message:      flags,
			Prefix:       prefix,
			PrefixLength: uint8(plen),
			Nexthops:     nexthops,
			Metric:       med,
		},
	}
}
Beispiel #2
0
func path2data(path *table.Path) (map[string]interface{}, map[string]string) {
	fields := map[string]interface{}{
		"RouterID": path.GetSource().ID,
	}
	if asPath := path.GetAsPath(); asPath != nil {
		fields["ASPath"] = asPath.String()
	}
	if origin, err := path.GetOrigin(); err == nil {
		typ := "-"
		switch origin {
		case bgp.BGP_ORIGIN_ATTR_TYPE_IGP:
			typ = "i"
		case bgp.BGP_ORIGIN_ATTR_TYPE_EGP:
			typ = "e"
		case bgp.BGP_ORIGIN_ATTR_TYPE_INCOMPLETE:
			typ = "?"
		}
		fields["Origin"] = typ
	}
	if med, err := path.GetMed(); err == nil {
		fields["Med"] = med
	}

	tags := map[string]string{
		"PeerAddress": path.GetSource().Address.String(),
		"PeerAS":      fmt.Sprintf("%v", path.GetSource().AS),
		"Timestamp":   path.GetTimestamp().String(),
	}
	if nexthop := path.GetNexthop(); len(nexthop) > 0 {
		fields["NextHop"] = nexthop.String()
	}
	if originAS := path.GetSourceAs(); originAS != 0 {
		fields["OriginAS"] = fmt.Sprintf("%v", originAS)
	}

	if err := bgp.FlatUpdate(tags, path.GetNlri().Flat()); err != nil {
		log.Error(err)
	}
	for _, p := range path.GetPathAttrs() {
		if err := bgp.FlatUpdate(tags, p.Flat()); err != nil {
			log.Error(err)
		}
	}
	return fields, tags
}
Beispiel #3
0
func path2data(path *table.Path) (map[string]interface{}, map[string]string) {
	fields := map[string]interface{}{
		"ASPath": path.GetAsPath().String(),
	}
	if origin, err := path.GetOrigin(); err == nil {
		typ := "-"
		switch origin {
		case bgp.BGP_ORIGIN_ATTR_TYPE_IGP:
			typ = "i"
		case bgp.BGP_ORIGIN_ATTR_TYPE_EGP:
			typ = "e"
		case bgp.BGP_ORIGIN_ATTR_TYPE_INCOMPLETE:
			typ = "?"
		}
		fields["Origin"] = typ
	}
	if med, err := path.GetMed(); err == nil {
		fields["Med"] = med
	}

	var prefix, prefixLen string
	l := strings.Split(path.GetNlri().String(), "/")
	if len(l) == 2 {
		prefix = l[0]
		prefixLen = l[1]
	}
	tags := map[string]string{
		"PeerAddress": path.GetSource().Address.String(),
		"PeerAS":      fmt.Sprintf("%v", path.GetSource().AS),
		"Prefix":      prefix,
		"PrefixLen":   prefixLen,
		"NextHop":     path.GetNexthop().String(),
		"OriginAS":    fmt.Sprintf("%v", path.GetSourceAs()),
		"Timestamp":   path.GetTimestamp().String(),
	}
	return fields, tags
}
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
}